def clear_metadata(fileobj: FileStorage, mime_type: str): resultIO = FileStorage() fileobj.seek(0) if mime_type in ("image/jpeg", "image/png"): image = Image.open(fileobj) if not image.info.get("exif"): return fileobj exifdata = Exif() exifdata.load(image.info["exif"]) # XXX: We want to remove all EXIF data except orientation (tag 274) or people will start seeing # rotated images... # Also, Pillow can't encode EXIF data, so we have to do it manually if exifdata.endian == "<": head = b"II\x2A\x00\x08\x00\x00\x00" else: head = b"MM\x00\x2A\x00\x00\x00\x08" ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) for tag, value in exifdata.items(): if tag == 274: ifd[tag] = value newExif = b"Exif\x00\x00" + head + ifd.tobytes(8) image.save(resultIO, format=Image.EXTENSION[EXTENSIONS[mime_type]], exif=newExif) return resultIO elif mime_type == "video/mp4": video = MP4(fileobj) video.clear() video.save(resultIO) return resultIO elif mime_type == "video/webm": # XXX: Mutagen doesn't seem to support webm files return fileobj
def clear_metadata(path: str, mime_type: str): if mime_type in ('image/jpeg', 'image/png'): image = Image.open(path) if not image.info.get('exif'): return image.save(path) exifdata = Exif() exifdata.load(image.info['exif']) # XXX: We want to remove all EXIF data except orientation (tag 274) or people will start seeing # rotated images... # Also, Pillow can't encode EXIF data, so we have to do it manually if exifdata.endian == "<": head = b"II\x2A\x00\x08\x00\x00\x00" else: head = b"MM\x00\x2A\x00\x00\x00\x08" ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) for tag, value in exifdata.items(): if tag == 274: ifd[tag] = value newExif = b"Exif\x00\x00" + head + ifd.tobytes(8) image.save(path, exif=newExif) elif mime_type == 'video/mp4': video = MP4(path) video.clear() video.save() elif mime_type == 'video/webm': # XXX: Mutagen doesn't seem to support webm files pass
def test_exif_orientation(image_files: Path): from PIL.Image import Exif im = np.load(image_files / "chelsea.npy") # original image is has landscape format assert im.shape[0] < im.shape[1] im_flipped = np.rot90(im, -1) exif_tag = Exif() exif_tag[274] = 6 # Set Orientation to 6 iio.v3.imwrite(image_files / "chelsea_tagged.png", im_flipped, plugin="pillow", exif=exif_tag) with iio.imopen( image_files / "chelsea_tagged.png", "r", plugin="pillow", ) as f: im_reloaded = f.read() im_meta = f.get_meta() # ensure raw image is now portrait assert im_reloaded.shape[0] > im_reloaded.shape[1] # ensure that the Exif tag is set in the file assert "Orientation" in im_meta and im_meta["Orientation"] == 6 im_reloaded = iio.v3.imread(image_files / "chelsea_tagged.png", plugin="pillow", rotate=True) assert np.array_equal(im, im_reloaded)
def test_legacy_exif_orientation(test_images, tmp_path): from PIL.Image import Exif im = np.load(test_images / "chelsea.npy") # original image is has landscape format assert im.shape[0] < im.shape[1] im_flipped = np.rot90(im, -1) exif_tag = Exif() exif_tag[274] = 6 # Set Orientation to 6 iio.v3.imwrite( tmp_path / "chelsea_tagged.png", im_flipped, plugin="pillow", exif=exif_tag, ) with iio.imopen( tmp_path / "chelsea_tagged.png", "r", legacy_mode=True, plugin="PNG-PIL", ) as f: im_reloaded = np.asarray(f.read()[0]) im_meta = f.get_meta() # ensure raw image is now portrait assert im_reloaded.shape[0] > im_reloaded.shape[1] # ensure that the Exif tag is set in the file assert "exif" in im_meta im_reloaded = iio.v3.imread(tmp_path / "chelsea_tagged.png", plugin="pillow", rotate=True) assert np.array_equal(im, im_reloaded)