2012-12-14 13 views
8

Mam następujący scenariusz:Obracanie obrazu o orientacji określonej w EXIF ​​przy użyciu Python bez PIL tym miniatury

  • przesyłam zdjęcie z iPhone wraz z informacjami EXIF ​​do mojego serwera gniazda Pyhon.
  • Potrzebuję, aby obraz był odpowiednio zorientowany na podstawie rzeczywistej orientacji, kiedy zdjęcie zostało zrobione. Wiem, że IOS zawsze zapisuje obraz jako Landscape Left i dodaje rzeczywistą orientację jako pole EXIF ​​(EXIF.Image.Orientation).
  • Czytam pole EXIF, aby zobaczyć rzeczywistą orientację. Następnie obracam obraz za pomocą wxpython do właściwej orientacji.

Używam pyexiv2 do manipulacji EXIF.

Problem: Informacje EXIF ​​zawierające miniatury utracone podczas obracania obrazu za pomocą wxpython.

Co zrobiłem: Czytam EXIF ​​przed obróceniem obrazu. Zresetowałem pole orientacji w EXIF. Potem odkładam to z powrotem po rotacji.

Problem:

Miniatura wewnątrz EXIF ​​nie jest obracany. Obraz i miniatura mają różne orientacje.

Pytania?

Czy istnieje moduł inny niż PIL, aby obrócić obraz zachowując informacje EXIF?

Czy istnieje osobne pole EXIF ​​dla orientacji miniatury?

Czy istnieje sposób, w jaki mogę samodzielnie obrócić tylko miniaturę?

Dzięki za pomoc ...

+0

Jeśli spojrzeć na stronie 56 [Exif 2.2 specyfikacji] (http://www.exif.org/Exif2-2.PDF), użytkownik Zobaczysz, że Orientacja jest opcjonalnym znacznikiem, który można dołączyć do miniatury w pierwszym IFD pliku. Nie mam żadnego doświadczenia z pyexiv2, ale jeśli umieścisz tagi na miniaturce w bibliotece, założę się, że możesz po prostu ustawić tę. – BenTrofatter

+0

@BenTrofatter Dzięki mate ... Próbowałem tego, ale większość widzów nawet nie spojrzy na EXIF ​​przed wyświetleniem obrazu/miniatury. Właśnie z tego powodu obróciłem obraz i zresetowałem EXIF. – ATOzTOA

Odpowiedz

2

znalazłem rozwiązanie ... to sprawdzić ... 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

Rozwiązanie to działa na mnie: PIL thumbnail is rotating my image?

Don Musisz sprawdzić, czy to iPhone lub iPad: , jeśli zdjęcie ma tag orientacji - obróć go.

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 

Przed:

Before

Po: After

+0

Czy również obraca miniaturę? – ATOzTOA

+0

Pracowałem jak zaklęcie, wślizgnąłem się do kodu, który już miałem, bez błędów. A + –

+0

Pracował jak urok! Dzięki za to. – FunkyMonk91

0

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

Ten blogu wyjaśnia to wyraźnie. Po prostu upewnij się, że próbujesz zachować kod @receiver.. w forms.py lub models.py, ponieważ mam błędy cannot import model/view.

zachować metodę rotate_image w models.py & @receiver.. kodu także w models.py.

Mam również błędy takie jak Brak takiego katalogu. Po prostu upewnij się, że full_path jest poprawnie ustawiony na folder multimediów.

użyłem tej linii

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

Powiązane problemy