def reorient_image(self, image): """ Re-orient image to required orientation to create collages """ try: if hasattr(image, '_getexif'): # only present in JPEGs for orientation in TAGS.keys(): if TAGS[orientation] == 'Orientation': break e = image._getexif() # returns None if no EXIF data if e is not None: exif = dict(e.items()) orientation = exif[orientation] # Make changes in the image according to the orientation if orientation == 2: image = image.transpose(Image.FLIP_LEFT_RIGHT) elif orientation == 3: image = image.transpose(Image.ROTATE_180) elif orientation == 4: image = image.transpose(Image.FLIP_TOP_BOTTOM) elif orientation == 5: image = image.transpose(Image.ROTATE_90).transpose( Image.FLIP_TOP_BOTTOM) elif orientation == 6: image = image.transpose(Image.ROTATE_270) elif orientation == 7: image = image.transpose(Image.ROTATE_270).transpose( Image.FLIP_TOP_BOTTOM) elif orientation == 8: image = image.transpose(Image.ROTATE_90) except Exception: print('Input image does not have metadata. Moving on..') pass return image
def rm_exifInfo(download_dir, out_dir): """移除exif信息""" img_list = os.listdir(download_dir) for f in img_list: image_file = os.path.join(download_dir, f) print("image file:{} ,\nexif info:{}".format( f, get_exif_data(image_file))) image = Image.open(image_file) # next 3 lines strip exif try: for orientation in TAGS.keys(): if TAGS[orientation] == 'Orientation': break print("exif :{}".format(image._getexif())) if image._getexif() is not None: exif = dict(image._getexif().items()) if exif.has_key(orientation): print("{} is {}".format(orientation, exif[orientation])) 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) except AttributeError: image = image data = list(image.getdata()) image_without_exif = Image.new(image.mode, image.size) image_without_exif.putdata(data) image_without_exif.save(os.path.join(out_dir, f))
def rotateImage(imgPath): im = Image.open(imgPath) srev = imgPath[::-1] ext = imgPath[len(srev) - srev.index("."):] if ext == "jpg" or ext == "jpeg": toRotate = True exifdict = im._getexif() if exifdict: for k in exifdict.keys(): if k in TAGS.keys(): if TAGS[k] == "Orientation": orientation = exifdict[k] if orientation == 3: im = im.rotate(180, expand=True) elif orientation == 6: im = im.rotate(270, expand=True) elif orientation == 8: im = im.rotate(90, expand=True) else: toRotate = False if toRotate: im.save(imgPath)
def handle_file(data, file_obj, uid=False): path = UPLOAD['media_root'] + file_obj.url(uid) make_dir(path) f = open(path, 'wb+') try: for chunk in data.chunks(): f.write(chunk) except AttributeError: # no chunks f.write(data) f.close() os.chmod(path, 0o777) try: im = Image.open(path) except IOError: os.remove(path) return False def fff(size): return Image.new('RGB', size, UPLOAD['fill_transparent']) # add white background to semi-transparent images if UPLOAD['fill_transparent'] and im.mode in ('RGBA', 'P'): bg = fff(im.size) im = Image.composite(im.convert('RGB'), bg, im.convert('RGBA')) # process soft rotation if im.mode == 'RGB': orientation = 1 try: exif = im._getexif() or {} except AttributeError: exif = {} for k in exif.keys(): if k in TAGS.keys() and TAGS[k] == 'Orientation': orientation = int(exif[k]) for transposition in TRANSPOSITION_CODES[orientation]: im = im.transpose(transposition) # convert all to RGB for JPEG if im.mode != 'RGB': im.convert('RGB') # larger canvas for images too small x, y = im.size MIN = 180 if x < MIN or y < MIN: w, h = x, y if w < MIN: w = MIN if h < MIN: h = MIN x1 = w//2 - x//2 y1 = h//2 - y//2 im2 = fff((w, h)) im2.paste(im, (x1,y1,x1+x,y1+y)) im = im2 # downsize large images down_to_x, down_to_y = UPLOAD['downsize_to'] if x > down_to_x or y > down_to_y: im.thumbnail(UPLOAD['downsize_to'], Image.ANTIALIAS) # crop off white edges if x > MIN and y > MIN: invert_im = ImageOps.invert(im) im = im.crop(invert_im.getbbox()) im.save(path, 'JPEG') return True
def read_one_exif_tag(pil_image, tag): try: exif_key = TAGS.keys()[TAGS.values().index(tag)] except ValueError: return 'Invalid EXIF Tag' info_ = pil_image._getexif() if info_ is None: return None else: invalid_str = 'Invalid EXIF Key: exif_key=%r, tag=%r' % (exif_key, tag) exif_val = info_.get(exif_key, invalid_str) return exif_val
def image_info(img): """Show information retrieved from image data.""" # pylint: disable=protected-access if USE_WAND: inkex.debug('Size:\t\t\t{} x {}'.format(int(img.size[0]), int(img.size[1]))) inkex.debug('Format:\t\t{}'.format(img.format)) inkex.debug('Mimetype:\t\t{}'.format(img.mimetype)) inkex.debug('Alpha channel:\t{}'.format(img.alpha_channel)) inkex.debug('Background:\t{}'.format(img.background_color)) inkex.debug('Matte color:\t{}'.format(img.matte_color)) inkex.debug('VirtualPixel:\t{}'.format(img.virtual_pixel)) inkex.debug('Colorspace:\t{}'.format(img.colorspace)) inkex.debug('Depth:\t\t{}'.format(img.depth)) inkex.debug('Orientation:\t{}'.format(img.orientation)) inkex.debug('Resolution:\t{}'.format(img.resolution)) inkex.debug('Type:\t\t{}'.format(img.type)) inkex.debug('Units:\t\t{}'.format(img.units)) if hasattr(img, 'metadata'): inkex.debug('\nMetadata:') for key, value in img.metadata.items(): inkex.debug('\t{}: {}'.format(key, value)) elif USE_PIL: inkex.debug('Size:\t\t\t{} x {}'.format(int(img.size[0]), int(img.size[1]))) inkex.debug('Format:\t\t{}'.format(img.format)) inkex.debug('Mode:\t\t{}'.format(img.mode)) if hasattr(img, 'info'): inkex.debug('\nInfo:') for key, value in img.info.items(): if key != "exif": # TODO: strings need attention (e.g. icc_profile) if isinstance(value, str): tagval = tuple(ord(c) for c in value) else: tagval = value inkex.debug('\t{}: {}'.format(key, tagval)) if hasattr(img, '_getexif'): inkex.debug('\nExif:') exif = img._getexif() if exif is not None: for (key, value) in six.iteritems(exif): if PIL_EXIF_TAGS and key in PIL_EXIF_TAGS.keys(): # TODO: more value formatting for PIL? if isinstance(value, str): tagval = tuple(ord(c) for c in value) else: tagval = value inkex.debug('\t{}: {}'.format(PIL_EXIF_TAGS.get(key), tagval)) else: raise RuntimeError(NO_MODULE)
def process(self, image): orientation = None for orientation in TAGS.keys(): if TAGS[orientation] == 'Orientation': break exif = dict(image.getexif().items()) if orientation in exif: 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) return image
def rotate(self): """Attempt to rotate image based on EXIF orientation tags. Raises: Exif.Invalid: if data does not contain orientation tags. """ self.image.seek(0) orientation = None for key in TAGS.keys(): if TAGS[key] == "Orientation": orientation = key break if orientation is None or orientation not in self.ROTATIONS: raise self.Invalid("Cannot find valid orientation key") self.image.rotate(self.ROTATIONS[orientation], expand=True)
def orientation_rotation(im): #take pil Image insctance and if need rotate it orientation = None try: exifdict = im._getexif() except AttributeError: exifdict = {} if exifdict: for k in exifdict.keys(): if k in TAGS.keys(): if TAGS[k] == 'Orientation': orientation = exifdict[k] if orientation in (3, 6, 8): if orientation == 6: im = im.rotate(-90) elif orientation == 8: im = im.rotate(90) elif orientation == 3: im = im.rotate(180) return im
def cleanup_image(filename): """ Create a smaller version of the image and rotate it if need be """ thumbfile = "thumb-%s" % filename im = Image.open(os.path.join(UPLOAD_FOLDER, filename)) exifdict = im._getexif() orientation = None if len(exifdict): for k in exifdict.keys(): if k in TAGS.keys() and TAGS[k] == 'Orientation': orientation = exifdict[k] if orientation == 3: im=im.rotate(180, expand=True) elif orientation == 6: im=im.rotate(270, expand=True) elif orientation == 8: im=im.rotate(90, expand=True) im.thumbnail(size, Image.ANTIALIAS) im.save(os.path.join(UPLOAD_FOLDER, thumbfile), "JPEG") return thumbfile
def export(event_name, targetdirectory = "gallery", jquery='jquery-2.0.3.min.js', show_time=False, author="Anonymous", verbose=False, db='~/.shotwell/data/photo.db'): db = sqlite3.connect(os.path.expanduser(db)) gallery = [] q = """\ SELECT strftime("%Y/%m/%d", datetime(PhotoTable.exposure_time, "unixepoch")), EventTable.name, PhotoTable.filename, PhotoTable.title, PhotoTable.rating, strftime("%Hh%M", datetime(PhotoTable.time_created, "unixepoch")) FROM PhotoTable LEFT JOIN EventTable ON PhotoTable.event_id = EventTable.id WHERE EventTable.name=?""" cur = db.cursor() result = cur.execute(q, (event_name,)).fetchall() nbr, i = len(result), 0 yield nbr for pic in result: i = i+1 if pic[4] == 0: yield "[%5.1f%%] Skip image (%d/5) %s/%s: %s\n" % (i/float(nbr)*100, pic[4], pic[0], pic[1], pic[2]) continue basename = '.'.join(os.path.basename(pic[2]).split('.')[:-1]) extension = os.path.basename(pic[2]).split('.')[-1] # create target directory d = os.path.join(targetdirectory, str(pic[0])) + '/' if not os.path.exists(d): os.makedirs(d) # create picture metadata descr = "" if show_time: descr = pic[5] if pic[3]: descr = descr + ", " if descr != "" else "" + str(pic[3]), # add tags else: descr = descr picture = dict( image = os.path.join('/', d, basename + '.' + extension), thumb = os.path.join('/', d, basename + '-sml.' + extension), big = os.path.join('/', d, basename + '-big.' + extension), title = pic[1], description = descr, link = os.path.join('/', d, basename + '.' + extension) ) yield "[%5.1f%%] Create image (%d/5) %s/%s: %s" % (i/float(nbr)*100, pic[4], pic[0], pic[1], basename+'.'+extension) # copy image file if os.path.exists(str(pic[2])) and not os.path.exists(os.path.join(d, os.path.basename(pic[2]))): shutil.copyfile(pic[2], os.path.join(d, os.path.basename(pic[2]))) # create thumbnail try : image = Image.open(os.path.join(d, os.path.basename(pic[2]))) for orientation in TAGS.keys() : if TAGS[orientation]=='Orientation' : break exif=dict(image._getexif().items()) if exif[orientation] == 3 : image=image.rotate(180, expand=True) image.save(os.path.join(d, os.path.basename(pic[2]))) elif exif[orientation] == 6 : image=image.rotate(270, expand=True) image.save(os.path.join(d, os.path.basename(pic[2]))) elif exif[orientation] == 8 : image=image.rotate(90, expand=True) image.save(os.path.join(d, os.path.basename(pic[2]))) yield " ; thumbnail " for r in (0.1, 'sml'), (0.2, 'mdm'), (0.75, 'big'): im2 = image.copy() im2.thumbnail((int(image.size[0] * r[0]) , int(image.size[1] * r[0])), Image.ANTIALIAS) im2.save(os.path.join(d, basename + '-{}'.format(r[1]) + '.' + extension)) yield r[1] + " " except: traceback.print_exc() else: yield " ; does already exist, not overwritten" # append to gallery gallery.append(picture) yield " ; added to gallery.\n" # enable javascript stuff yield "Copying the resources.\n" if not os.path.exists(os.path.join(targetdirectory, 'rsrc')): os.makedirs(os.path.join(targetdirectory, 'rsrc')) pkg_dir = os.path.abspath(os.path.join(os.path.split(__file__)[0], '..')) shutil.copyfile(os.path.join(pkg_dir, 'contrib', jquery), os.path.join(targetdirectory, 'rsrc', jquery)) shutil.copyfile(os.path.join(pkg_dir, 'contrib/galleria/src/galleria.js',), os.path.join(targetdirectory, 'rsrc', 'galleria.js')) shutil.copyfile(os.path.join(pkg_dir, 'contrib/galleria/src/themes/classic/galleria.classic.js',), os.path.join(targetdirectory, 'rsrc', 'galleria.classic.js')) shutil.copyfile(os.path.join(pkg_dir, 'contrib/galleria/src/themes/classic/galleria.classic.css',), os.path.join(targetdirectory, 'rsrc', 'galleria.classic.css')) shutil.copyfile(os.path.join(pkg_dir, 'contrib/galleria/src/themes/classic/classic-loader.gif',), os.path.join(targetdirectory, 'rsrc', 'classic-loader.gif')) shutil.copyfile(os.path.join(pkg_dir, 'contrib/galleria/src/themes/classic/classic-map.png',), os.path.join(targetdirectory, 'rsrc', 'classic-map.png')) yield "Creating index file...\n" # create index with open(os.path.join(targetdirectory, 'index.html'), 'w') as idx: idx.write(WEBPAGE_TPL.format(title=event_name, data=json.dumps(gallery), cred=author))
def handle_file(data, file_obj): path = file_obj.path() make_dir(path) f = open(path, 'wb+') try: for chunk in data.chunks(): f.write(chunk) except AttributeError: # no chunks f.write(data) f.close() os.chmod(path, 0o777) try: im = Image.open(path) except IOError: os.remove(path) return False def fff(size): return Image.new('RGB', size, app_settings.UPLOAD_FILL_ALPHA) # add white background to semi-transparent images if app_settings.UPLOAD_FILL_ALPHA and im.mode in ('RGBA', 'P'): bg = fff(im.size) im = Image.composite(im.convert('RGB'), bg, im.convert('RGBA')) # process soft rotation if im.mode == 'RGB': orientation = 1 try: exif = im._getexif() or {} except AttributeError: exif = {} for k in exif.keys(): if k in TAGS.keys() and TAGS[k] == 'Orientation': orientation = int(exif[k]) for transposition in TRANSPOSITION_CODES[orientation]: im = im.transpose(transposition) # convert all to RGB for JPEG if im.mode != 'RGB': im.convert('RGB') # larger canvas for images too small x, y = im.size MIN = 180 if x < MIN or y < MIN: w, h = x, y if w < MIN: w = MIN if h < MIN: h = MIN x1 = w//2 - x//2 y1 = h//2 - y//2 im2 = fff((w, h)) im2.paste(im, (x1, y1, x1+x, y1+y)) im = im2 # downsize large images down_to_x, down_to_y = app_settings.UPLOAD_DOWNSIZE_TO if x > down_to_x or y > down_to_y: im.thumbnail(app_settings.UPLOAD_DOWNSIZE_TO, Image.ANTIALIAS) # autocrop if x > MIN and y > MIN: im = autocrop(im) im.save(path, 'JPEG') save_sizes(file_obj) return im
def copyFileToStorage(data={}, istorage=''): thumb_sizes = {'thumb': (250, 250), 'normal': (1280, 1280)} new_size = 0 try: #if data['ext'] == 'JPG': pyear = os.path.join(istorage, data['image'].split('/')[0]) pmonth = os.path.join(pyear, data['image'].split('/')[1]) pfile = os.path.join(istorage, data['image']) if not os.path.exists(pyear): os.makedirs(pyear) if not os.path.exists(pmonth): os.makedirs(pmonth) data['orig_path'] = data['orig_path'] #unicode(data['orig_path']) #shutil.copy2(data['orig_path'], pfile) print(data['orig_path'], pfile) copyFile(data['orig_path'], pfile) isimg = 0 try: z = Image.open(pfile) isimg = 1 except: pass if '.THM' in pfile: isimg = 0 if isimg: z = Image.open(pfile) for orientation in TAGS.keys(): if TAGS[orientation] == 'Orientation': break if '_getexif' in dir(z): fex = z._getexif() else: fex = None if fex: exif = dict(z._getexif().items()) if exif.get(orientation, '*') != '*': if exif[orientation] == 3: z = z.rotate(180, expand=True) elif exif[orientation] == 6: z = z.rotate(270, expand=True) new_size = 1 elif exif[orientation] == 8: z = z.rotate(90, expand=True) new_size = 1 z.save(pfile, quality=100) #print new_size #TODO: здесь какой-то косяк происходит, не копируются exif данные #/mnt/drive_d/PHOTO_IMPORT/Анина свадьба 13.07.13/IMG_1785.JPG /mnt/drive_d/PHOTO_STORAGE/2013/07/20130712104615862913.JPG #try: # oldmeta = pyexiv2.ImageMetadata(data['orig_path']) # oldmeta.read() # # newmeta = pyexiv2.ImageMetadata(pfile) # newmeta.read() # oldmeta.copy(newmeta) # new_size = z.size # newmeta['Exif.Image.Orientation'] = 1 # newmeta["Exif.Photo.PixelXDimension"] = z.size[0] # newmeta["Exif.Photo.PixelYDimension"] = z.size[1] # newmeta.write() #except: # print 'ZZZ: meta bag' for thms in thumb_sizes.keys(): th_p = os.path.join(istorage, thms) th_pyear = os.path.join(th_p, data['image'].split('/')[0]) th_pmonth = os.path.join(th_pyear, data['image'].split('/')[1]) th_pfile = os.path.join(istorage, thms, data['image']) if not os.path.exists(th_p): os.makedirs(th_p) if not os.path.exists(th_pyear): os.makedirs(th_pyear) if not os.path.exists(th_pmonth): os.makedirs(th_pmonth) try: if not data['is_img']: z = Image.open(pfile) if thms == 'thumb': width, height = z.size if width > height: delta = width - height left = int(delta / 2) upper = 0 right = height + left lower = height else: delta = height - width left = 0 upper = int(delta / 2) right = width lower = width + upper z = z.crop((left, upper, right, lower)) z.thumbnail(thumb_sizes[thms], Image.ANTIALIAS) z.save(th_pfile, quality=75) except: pass else: pass #else: except: return (0, new_size) return (1, new_size)
import os, logging from PIL import Image as pImage, ImageOps from PIL.ExifTags import TAGS # Compute 'reverse' exif TAGS RTAGS = {} for k in TAGS.keys(): RTAGS[TAGS[k]] = k from django.dispatch import receiver from django.db.models.signals import post_delete, post_save from gallery.models import Image Logger = logging.getLogger(__name__) # Delete image files from disk when image objects are deleted @receiver(post_delete, sender=Image) def on_delete(sender, **kwargs): img = kwargs['instance'] # First delete cache files. The cache directory holding the photo variants is: cache_dir = os.path.commonpath((img.preview.path, img.thumbnail.path)) for d in (img.preview, img.thumbnail): if d.storage.exists(d.path): d.storage.delete(d.path) # Delete each variant if os.path.exists(cache_dir): try: os.rmdir(cache_dir) except OSError: # Cache dirs can end up shared if two photos/images have the same basename # but different suffix (e.g.: 'jpeg' and 'jpg' or 'png', etc Logger.info(
from PIL import Image from PIL.ExifTags import TAGS img = Image.open('IMG_7408.JPG') exifdict = img._getexif() if len(exifdict): for k in exifdict.keys(): if k in TAGS.keys(): print (TAGS[k], exifdict[k]) else: print (k, exifdict[k])