def _get_png_implied_rotation(pixbuf_or_image): """Same as <get_implied_rotation> for PNG files. Lookup for Exif data in the tEXt chunk. """ if isinstance(pixbuf_or_image, gtk.gdk.Pixbuf): exif = pixbuf_or_image.get_option('tEXt::Raw profile type exif') elif isinstance(pixbuf_or_image, Image.Image): exif = pixbuf_or_image.info.get('Raw profile type exif') else: raise ValueError() if exif is None: return None exif = exif.split('\n') if len(exif) < 4 or 'exif' != exif[1]: # Not valid Exif data. return None size = int(exif[2]) try: data = binascii.unhexlify(''.join(exif[3:])) except TypeError: # Not valid hexadecimal content. return None if size != len(data): # Sizes should match. return None im = namedtuple('FakeImage', 'info')({ 'exif': data }) exif = _getexif(im) orientation = exif.get(274, None) if orientation is not None: orientation = str(orientation) return orientation
def pil_to_pixbuf(im, keep_orientation=False): """Return a pixbuf created from the PIL <im>.""" if im.mode.startswith('RGB'): has_alpha = im.mode == 'RGBA' elif im.mode in ('LA', 'P'): has_alpha = True else: has_alpha = False target_mode = 'RGBA' if has_alpha else 'RGB' if im.mode != target_mode: im = im.convert(target_mode) pixbuf = gtk.gdk.pixbuf_new_from_data( im.tobytes(), gtk.gdk.COLORSPACE_RGB, has_alpha, 8, im.size[0], im.size[1], (4 if has_alpha else 3) * im.size[0] ) if keep_orientation: # Keep orientation metadata. orientation = None exif = im.info.get('exif') if exif is not None: exif = _getexif(im) orientation = exif.get(274, None) if orientation is None: # Maybe it's a PNG? Try alternative method. orientation = _get_png_implied_rotation(im) if orientation is not None: setattr(pixbuf, 'orientation', str(orientation)) return pixbuf
def _getexif(self): from PIL.JpegImagePlugin import _getexif return _getexif(self)