2012-12-14 8 views
8

Ho il seguente scenario:Rotazione di un'immagine con orientamento specificato nel EXIF ​​utilizzando Python senza PIL compresa la miniatura

  • io mando una foto da iPhone con le informazioni EXIF ​​al mio server socket Pyhon.
  • Ho bisogno che l'immagine sia orientata correttamente in base all'orientamento effettivo quando è stata scattata l'immagine. So che IOS salva sempre l'immagine come Paesaggio a sinistra e aggiunge l'orientamento attuale come campo EXIF ​​(EXIF.Image.Orientation).
  • Sto leggendo il campo EXIF ​​per vedere l'orientamento attuale. Quindi sto ruotando l'immagine usando wxpython per l'orientamento corretto.

Sto usando pyexiv2 per la manipolazione EXIF.

Problema: le informazioni EXIF ​​che includono le anteprime perse ruotando l'immagine con wxpython.

Cosa ho fatto: Sto leggendo l'EXIF prima di ruotare l'immagine. Ho ripristinato il campo di orientamento in EXIF. Quindi lo rimetto dopo la rotazione.

Il problema:

La miniatura all'interno del EXIF ​​non viene ruotata. Pertanto, l'immagine e la miniatura hanno orientamenti diversi.

Domande?

Esiste un modulo diverso da PIL per ruotare un'immagine mantenendo le sue informazioni EXIF?

Esiste un campo EXIF ​​separato per l'orientamento delle miniature?

C'è un modo per ruotare solo la miniatura?

Grazie per il vostro aiuto ...

+0

Se si dà un'occhiata alla pagina 56 del [Exif 2.2 spec] (http://www.exif.org/Exif2-2.PDF), è Vedremo che l'Orientamento è un tag opzionale che può essere allegato alla miniatura nel 1 ° IFD del file. Non ho alcuna esperienza con pyexiv2, ma se puoi impostare tag nella miniatura attraverso la libreria, scommetto che puoi semplicemente impostare questo. – BenTrofatter

+0

@BenTrofatter Grazie amico ... Ho provato questo, ma la maggior parte degli spettatori non guarderà nemmeno EXIF ​​prima di visualizzare l'immagine/anteprima. Questo è stato il motivo per cui ho ruotato l'immagine e ripristinato EXIF. – ATOzTOA

risposta

2

ho trovato una soluzione ... check this out ... http://www.atoztoa.com/2012/12/rotate-images-along-with-thumbnails-in.html

''' 
Rotate Image 
''' 
import pyexiv2 
import wx 
import cStringIO 
import os 

def rotateImage(infile, device): 
    try: 
     # Read Metadata from the image 
     metadata = pyexiv2.metadata.ImageMetadata(infile) 
     metadata.read(); 

     # Let's get the orientation 
     orientation = metadata.__getitem__("Exif.Image.Orientation") 
     orientation = int(str(orientation).split("=")[1][1:-1]) 

     # Extract thumbnail 
     thumb = metadata.exif_thumbnail 

     angle = 0 

     # Check the orientation field in EXIF and rotate image accordingly 
     if device == "iPhone" or device == "iPad": 
      # Landscape Left : Do nothing 
      if orientation == ORIENTATION_NORMAL: 
       angle = 0 
      # Portrait Normal : Rotate Right 
      elif orientation == ORIENTATION_LEFT: 
       angle = -90 
      # Landscape Right : Rotate Right Twice 
      elif orientation == ORIENTATION_DOWN: 
       angle = 180 
      # Portrait Upside Down : Rotate Left 
      elif orientation == ORIENTATION_RIGHT: 
       angle = 90 

      # Resetting Exif field to normal 
      print "Resetting exif..." 
      orientation = 1 
      metadata.__setitem__("Exif.Image.Orientation", orientation) 

     # Rotate 
     if angle != 0: 
      # Just rotating the image based on the angle 
      print "Rotating image..." 
      angle = math.radians(angle) 
      img = wx.Image(infile, wx.BITMAP_TYPE_ANY) 
      img_centre = wx.Point(img.GetWidth()/2, img.GetHeight()/2) 
      img = img.Rotate(angle, img_centre, True) 
      img.SaveFile(infile, wx.BITMAP_TYPE_JPEG) 

      # Create a stream out of the thumbnail and rotate it using wx 
      # Save the rotated image to a temporary file 
      print "Rotating thumbnail..." 
      t = wx.EmptyImage(100, 100) 
      thumbStream = cStringIO.StringIO(thumb.data) 
      t.LoadStream(thumbStream, wx.BITMAP_TYPE_ANY) 
      t_centre = wx.Point(t.GetWidth()/2, t.GetHeight()/2) 
      t = t.Rotate(angle, t_centre, True) 
      t.SaveFile(infile + ".jpg", wx.BITMAP_TYPE_JPEG) 
      thumbStream.close() 

      # Read the rotated thumbnail and put it back in the rotated image 
      thumb.data = open(infile + ".jpg", "rb").read(); 
      # Remove temporary file 
      os.remove(infile + ".jpg") 

     # Write back metadata 
     metadata.write(); 

    except Exception, e: 
     print "Error rotating image... : " + str(e) 
22

Questa soluzione funziona per me: PIL thumbnail is rotating my image?

Don Non è necessario verificare se si tratta di iPhone o iPad: se la foto ha tag di orientamento - ruotarlo.

from PIL import Image, ExifTags 

try: 
    image=Image.open(filepath) 
    for orientation in ExifTags.TAGS.keys(): 
     if ExifTags.TAGS[orientation]=='Orientation': 
      break 
    exif=dict(image._getexif().items()) 

    if exif[orientation] == 3: 
     image=image.rotate(180, expand=True) 
    elif exif[orientation] == 6: 
     image=image.rotate(270, expand=True) 
    elif exif[orientation] == 8: 
     image=image.rotate(90, expand=True) 
    image.save(filepath) 
    image.close() 

except (AttributeError, KeyError, IndexError): 
    # cases: image don't have getexif 
    pass 

Prima:

Before

Dopo: After

+0

Ruota anche la miniatura? – ATOzTOA

+0

Ha funzionato come un fascino, è scivolato direttamente nel codice di caricamento che avevo già, senza errori. A + –

+0

Ha funzionato come un fascino! Grazie per questo. – FunkyMonk91

0

https://medium.com/@giovanni_cortes/rotate-image-in-django-when-saved-in-a-model-8fd98aac8f2a

Questo post del blog lo spiega chiaramente. Assicurati di provare a mantenere il codice @receiver.. in forms.py o models.py perché ho ricevuto gli errori cannot import model/view.

mantenere il metodo rotate_image in models.py & @receiver.. codice anche in models.py.

Ho anche ricevuto errori come No directory. Assicurati che full_path sia impostato correttamente sulla cartella multimediale.

Ho usato questa linea

fullpath = os.path.join(os.path.dirname(BASE_DIR)) + instance.fimage.url

Problemi correlati