def generateThumbnails(photos, height, directory): for photo in photos: img = Image.open(photo) size = img.size orientation = img.getexif()[0x0112] if orientation > 4: size = size[::-1] old_w, old_h = size width = math.ceil(old_w / old_h * height) target = (width, height) if orientation > 4: target = target[::-1] img.thumbnail(target) ifd = ImageFileDirectory_v2() ifd[0x0112] = orientation out = BytesIO() ifd.save(out) exif = b"Exif\x00\x00" + out.getvalue() img.save(f"{directory}/{os.path.basename(photo)}", exif=exif)
def _write_tiff(path, image_data, meta_dict={}): from PIL import Image from PIL.TiffTags import TAGS, lookup from PIL.TiffImagePlugin import ImageFileDirectory_v2 image_data = _standardize_axis_order(image_data, 'tiff') h, w, d = image_data.shape imgList = [] # TODO: data type should be determined by input image_data # this complicated bit ensures data is saved as 16bit for i in range(d): imgList.append(Image.new('I;16', image_data.shape[:-1])) slc = image_data[..., i] slice_bytes = slc.astype( slc.dtype.newbyteorder('<')).tobytes(order='F') imgList[i].frombytes(slice_bytes) # hack to invert TAGS dictionary, does not support non one-to-one dicts TAGS_keys, TAGS_values = list(TAGS.keys()), list(TAGS.values()) TAGSinv = {v: k for v, k in zip(TAGS_values, TAGS_keys)} img_meta_dict = ImageFileDirectory_v2() for key in meta_dict.keys(): if key in TAGSinv.keys(): tag_info = lookup(TAGSinv[key]) img_meta_dict[tag_info.value] = meta_dict[key] img_meta_dict.tagtype[tag_info.value] = tag_info.type imgList[0].save(path, save_all=True, append_images=imgList[1:], compression='tiff_deflate', tiffinfo=img_meta_dict)
def save_tiff(self, filename): """Save the ImageFile as a tiff image with metadata.""" from PIL.TiffImagePlugin import ImageFileDirectory_v2 import json im = Image.fromarray(self.image.asint(np.uint32), mode="I") ifd = ImageFileDirectory_v2() ifd[270] = json.dumps(self.metadata.export_all()) tiffname = os.path.splitext(filename)[0] + '.tiff' im.save(tiffname, tiffinfo=ifd)
def get_user_comment_exif_bytes(user_comment=""): """ Returns the bytes for EXIF tags containing only the given user comment """ ifd = ImageFileDirectory_v2() ifd[__TAGS_r[__USER_COMMENT_TAG]] = user_comment ifd.tagtype[__TAGS_r[__USER_COMMENT_TAG]] = __EXIF_STRING_TYPE out = BytesIO() ifd.save(out) exif = b"Exif\x00\x00" + out.getvalue() return exif
def to_tiff(self, filename): """Save the ImageArray as a tiff image with metadata. Args: filename (str): Filename to save file as. Note: PIL can save in modes "L" (8bit unsigned int), "I" (32bit signed int), or "F" (32bit signed float). In general max info is preserved for "F" type so if forcetype is not specified then this is the default. For boolean type data mode "L" will suffice and this is chosen in all cases. The type name is added as a string to the metadata before saving. """ metadata_export = [] imlist = [] for d in self._marshall(): dtype = np.dtype( d.dtype).name # string representation of dtype we can save d["ImageArray.dtype"] = dtype # add the dtype to the metadata for saving. metadata_export.append(d.metadata.export_all()) if d.dtype.kind == "b": # boolean we're not going to lose data by saving as unsigned int imlist.append(Image.fromarray(d.image, mode="L")) else: try: imlist.append(Image.fromarray(d.image)) except TypeError: imlist.append(Image.fromarray(d.image.astype("float32"))) ifd = ImageFileDirectory_v2() ifd[270] = dumps({ "type": self.__class__.__name__, "module": self.__class__.__module__, "layout": self.layout, "metadata": metadata_export, }) ext = path.splitext(filename)[1] if ext in [".tif", ".tiff"]: # ensure extension is preserved in save pass else: # default to tiff ext = ".tiff" tiffname = path.splitext(filename)[0] + ext imlist[0].save(tiffname, save_all=True, append_images=imlist[1:], tiffinfo=ifd) return self
def _buildHeader(self, imageinfo): ifd = ImageFileDirectory_v2() ifd[TAGMAP['startx'][0]] = 1 ifd[TAGMAP['starty'][0]] = 1 for (dev, attr), attrVal in imageinfo.items(): key = '%s/%s' % (dev, attr) if key in TAGMAP: tag = TAGMAP[key][0] typ = TAGMAP[key][2] ifd.tagtype[tag] = typ if typ == 11: attrVal = float(attrVal[0]) ifd[tag] = attrVal ifd = dict(ifd) # increase stripoffset, otherwise ESMERALDA can not read meta data ifd[STRIPOFFSETS] = 186 return ifd