def jpg_with_tags(scratch_directory): """A JPEG file with several tags, used by a bunch of tests. This fixture creates the file itself and returns its pathname. The file is made read-only for safety. N.B. we use NamedTemporaryFile(delete=False) because we want to be able to close the initial file descriptor, to avoid tripping over Windows' exclusive file access rules. Cleanup is handled by the teardown of the scratch_directory fixture. """ with tempfile.NamedTemporaryFile(dir=scratch_directory, suffix='.jpg', delete=False) as fp: fp.write(EMPTY_JPG_DATA) name = fp.name # Write some metadata m = ImageMetadata(name) m.read() m['Exif.Image.Make'] = 'EASTMAN KODAK COMPANY' m['Exif.Image.DateTime'] = datetime.datetime(2009, 2, 9, 13, 33, 20) m['Iptc.Application2.Caption'] = ['blabla'] m['Iptc.Application2.DateCreated'] = [datetime.date(2004, 7, 13)] m['Xmp.dc.format'] = ('image', 'jpeg') m['Xmp.dc.subject'] = ['image', 'test', 'pyexiv2'] m.comment = 'Hello World!' m.write() del m os.chmod(name, 0o0400) # r-------- return name
def test_write_dont_preserve_timestamps(self): stat = os.stat(self.pathname) atime = round(stat.st_atime) mtime = round(stat.st_mtime) metadata = ImageMetadata(self.pathname) metadata.read() metadata.comment = 'Yellow Submarine' time.sleep(1.1) metadata.write() stat2 = os.stat(self.pathname) atime2 = round(stat2.st_atime) mtime2 = round(stat2.st_mtime) # It is not safe to assume that atime will have been modified when the # file has been read, as it may depend on mount options (e.g. noatime, # relatime). # See discussion at http://bugs.launchpad.net/pyexiv2/+bug/624999. #self.failIfEqual(atime2, atime) self.failIfEqual(mtime2, mtime) metadata.comment = 'Yesterday' time.sleep(1.1) metadata.write(preserve_timestamps=True) stat3 = os.stat(self.pathname) atime3 = round(stat3.st_atime) mtime3 = round(stat3.st_mtime) self.failUnlessEqual(atime3, atime2) self.failUnlessEqual(mtime3, mtime2)
def _test_add_comment(self, value): metadata = ImageMetadata(self.pathname) metadata.read() key = 'Exif.Photo.UserComment' metadata[key] = value metadata.write() metadata = ImageMetadata(self.pathname) metadata.read() self.assert_(key in metadata.exif_keys) tag = metadata[key] self.assertEqual(tag.value, value)
def test_add_comment(value, uc_empty): metadata = ImageMetadata(uc_empty) metadata.read() key = 'Exif.Photo.UserComment' metadata[key] = value metadata.write() metadata = ImageMetadata(uc_empty) metadata.read() assert key in metadata.exif_keys tag = metadata[key] assert tag.type == 'Comment' assert tag.value == value
def _test_add_comment(self, value): metadata = ImageMetadata(self.pathname) metadata.read() key = 'Exif.Photo.UserComment' metadata[key] = value metadata.write() metadata = ImageMetadata(self.pathname) metadata.read() self.assert_(key in metadata.exif_keys) tag = metadata[key] self.assertEqual(tag.type, 'Comment') self.assertEqual(tag.value, value)
def test_write_preserve_timestamps(self): stat = os.stat(self.pathname) atime = round(stat.st_atime) mtime = round(stat.st_mtime) metadata = ImageMetadata(self.pathname) metadata.read() metadata.comment = 'Yellow Submarine' time.sleep(1.1) metadata.write(preserve_timestamps=True) stat2 = os.stat(self.pathname) atime2 = round(stat2.st_atime) mtime2 = round(stat2.st_mtime) self.failUnlessEqual(atime2, atime) self.failUnlessEqual(mtime2, mtime)
def setUp(self): # Create an empty image file fd, self.pathname = tempfile.mkstemp(suffix='.jpg') os.write(fd, EMPTY_JPG_DATA) os.close(fd) # Write some metadata m = ImageMetadata(self.pathname) m.read() m['Exif.Image.Make'] = 'EASTMAN KODAK COMPANY' m['Exif.Image.DateTime'] = datetime.datetime(2009, 2, 9, 13, 33, 20) m['Iptc.Application2.Caption'] = ['blabla'] m['Iptc.Application2.DateCreated'] = [datetime.date(2004, 7, 13)] m['Xmp.dc.format'] = ('image', 'jpeg') m['Xmp.dc.subject'] = ['image', 'test', 'pyexiv2'] m.comment = 'Hello World!' m.write() self.metadata = ImageMetadata(self.pathname)
def add_metadata(image, meta_dict, path_to_data_dir="", filename=None, delete_file=True): """Add meta data to an given image. Process: uuid is generated for a unique filename. Image will be stored locally, because ImageMetadata object need to receive filepath. TODO: Might work without save image on local storage. :param image: Pillow Image which where meta information should be stored in :type image: PIL.Image :param meta_dict: Dict with meta information. E.g. meta_dict={"color":["red","green"], "hex":["#ff0000", "#00ff00"]} :type meta_dict: [type] :param path_to_data_dir: Optional path of image_file. Local file will be removed within function anyway, therefore this paramter is not impportant. :type path_to_data_dir: str :return: [description] :rtype: [type] """ Path(path_to_data_dir).mkdir(parents=True, exist_ok=True) # download file to write new meta data to file if not filename: media_guid = uuid.uuid4().hex filename = path_to_data_dir + media_guid + '.jpg' image.save(filename) # add metadata meta = ImageMetadata(filename) meta.read() meta['Exif.Photo.UserComment'] = json.dumps(meta_dict) meta.write() # transform back to PIL Image byteio = BytesIO(meta.buffer) image = Image.open(byteio) # delete file if delete_file: os.remove(filename) # return image with meta information return image
def edit_exif(self): """Manipulations with exif (adding copyright).""" from pyexiv2.metadata import ImageMetadata from pyexiv2.exif import ExifValueError, ExifTag info_to_exif = ('File was downloaded from gallery {0}. \n' 'URL of image: {1} \n' 'Author: {2}'.format( url, self.image_url, self.author)) try: metadata = ImageMetadata(self.filename) metadata.read() if 'Exif.Image.Copyright' in metadata: info_to_exif = metadata['Exif.Image.Copyright'].value + '\n' + info_to_exif metadata['Exif.Image.Copyright'] = info_to_exif metadata.write() except ExifValueError, info: logging.debug('error parsing Exit. %s' % info) self.error = True