Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    def test_makernote_types(self):
        # Makernote tags not attached to an image have an Undefined type by
        # default. When read from an existing image though, their type should be
        # correctly set (see https://bugs.launchpad.net/pyexiv2/+bug/781464).
        tag1 = ExifTag('Exif.Pentax.PreviewResolution')
        tag1.raw_value = '640 480'
        self.assertEqual(tag1.type, 'Undefined')
        self.failUnlessRaises(ValueError, getattr, tag1, 'value')
        tag2 = ExifTag('Exif.Pentax.CameraInfo')
        tag2.raw_value = '76830 20070527 2 1 4228109'
        self.assertEqual(tag2.type, 'Undefined')
        self.failUnlessRaises(ValueError, getattr, tag2, 'value')

        filepath = testutils.get_absolute_file_path(
            os.path.join('data', 'pentax-makernote.jpg'))
        checksum = '646804b309a4a2d31feafe9bffc5d7f0'
        self.assert_(testutils.CheckFileSum(filepath, checksum))
        metadata = ImageMetadata(filepath)
        metadata.read()
        tag1 = metadata[tag1.key]
        self.assertEqual(tag1.type, 'Short')
        self.assertEqual(tag1.value, [640, 480])
        tag2 = metadata[tag2.key]
        self.assertEqual(tag2.type, 'Long')
        self.assertEqual(tag2.value, [76830L, 20070527L, 2L, 1L, 4228109L])
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 def _read_image(self, filename):
     filepath = testutils.get_absolute_file_path(
         os.path.join('data', filename))
     self.assert_(testutils.CheckFileSum(filepath,
                                         self.checksums[filename]))
     m = ImageMetadata(filepath)
     m.read()
     return m
Exemplo n.º 8
0
    def test_from_file_and_from_buffer(self):
        # from file
        m1 = ImageMetadata(self.filepath)
        m1.read()
        self.assertEqual(hashlib.md5(m1.buffer).hexdigest(), self.md5sum)

        # from buffer
        m2 = self._metadata_from_buffer()
        self.assertEqual(hashlib.md5(m2.buffer).hexdigest(), self.md5sum)
Exemplo n.º 9
0
def test_from_file_and_from_buffer(smiley):
    # from file
    m1 = ImageMetadata(smiley.filepath)
    m1.read()
    assert hashlib.md5(m1.buffer).hexdigest() == smiley.md5sum

    # from buffer
    m2 = metadata_from_buffer(smiley)
    assert hashlib.md5(m2.buffer).hexdigest() == smiley.md5sum
Exemplo n.º 10
0
def metadata_rw(jpg_with_tags, scratch_directory):
    """A fresh *writable* ImageMetadata object for a *copy* of the
       jpg_with_tags.  Returns a 2-tuple (pathname, ImageMetadata).
       read() has not yet been called.
    """
    (nfd, nname) = tempfile.mkstemp(suffix='.jpg', dir=scratch_directory)
    # create ofp first so that nfd is closed even if the second open throws
    with open(nfd, "wb") as ofp, open(jpg_with_tags, "rb") as ifp:
        shutil.copyfileobj(ifp, ofp)
    # nfd is now closed
    os.chmod(nname, 0o0600)  # rw-------
    return MetadataWithPath(nname, ImageMetadata(nname))
Exemplo n.º 11
0
def test_read_from_filename(tempdir, filename):
    if isinstance(filename, bytes):
        tempdir = tempdir.encode("ascii")
    filepath = os.path.join(tempdir, filename)
    try:
        with open(filepath, 'wb') as fd:
            fd.write(UNUSUAL_JPG_DATA)
    except OSError as e:
        # The OS might not let us create files with some of the above names.
        pytest.skip("could not create test file: " + str(e))

    m = ImageMetadata(filepath)
    m.read()
    assert m['Exif.Image.DateTime'].value.isoformat() == UNUSUAL_JPG_DATETIME
Exemplo n.º 12
0
 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)
Exemplo n.º 13
0
def image_read_exif(filename):
    data = ImageMetadata(filename)

    # This reads the metadata and closes the file
    data.read()

    lens_model = None
    tag = 'Exif.Photo.LensModel'
    if has_exif_tag(data, tag):
        lens_model = data[tag].value
    else:
        tag = 'Exif.NikonLd3.LensIDNumber'
        if has_exif_tag(data, tag):
            lens_model = data[tag].human_value

        tag = 'Exif.Panasonic.LensType'
        if has_exif_tag(data, tag):
            lens_model = data[tag].value

        tag = 'Exif.Sony1.LensID'
        if has_exif_tag(data, tag):
            lens_model = data[tag].human_value

        tag = 'Exif.Minolta.LensID'
        if has_exif_tag(data, tag):
            lens_model = data[tag].human_value

    if lens_model is None:
       lens_model = 'Standard'

    tag = 'Exif.Photo.FocalLength'
    if has_exif_tag(data, tag):
        focal_length = float(data[tag].value)
    else:
        print("%s doesn't have Exif.Photo.FocalLength set. " % (filename) +
              "Please fix it manually.")

    tag = 'Exif.Photo.FNumber'
    if has_exif_tag(data, tag):
        aperture = float(data[tag].value)
    else:
        print("%s doesn't have Exif.Photo.FNumber set. " % (filename) +
              "Please fix it manually.")

    return { "lens_model" : lens_model,
             "focal_length" : focal_length,
             "aperture" : aperture }
Exemplo n.º 14
0
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
Exemplo n.º 15
0
 def test_not_read_raises(self):
     # http://bugs.launchpad.net/pyexiv2/+bug/687373
     self.assertRaises(IOError, self.metadata.write)
     self.assertRaises(IOError, getattr, self.metadata, 'dimensions')
     self.assertRaises(IOError, getattr, self.metadata, 'mime_type')
     self.assertRaises(IOError, getattr, self.metadata, 'exif_keys')
     self.assertRaises(IOError, getattr, self.metadata, 'iptc_keys')
     self.assertRaises(IOError, getattr, self.metadata, 'xmp_keys')
     self.assertRaises(IOError, self.metadata._get_exif_tag,
                       'Exif.Image.Make')
     self.assertRaises(IOError, self.metadata._get_iptc_tag,
                       'Iptc.Application2.Caption')
     self.assertRaises(IOError, self.metadata._get_xmp_tag, 'Xmp.dc.format')
     self.assertRaises(IOError, self.metadata._set_exif_tag,
                       'Exif.Image.Make', 'foobar')
     self.assertRaises(IOError, self.metadata._set_iptc_tag,
                       'Iptc.Application2.Caption', ['foobar'])
     self.assertRaises(IOError, self.metadata._set_xmp_tag, 'Xmp.dc.format',
                       ('foo', 'bar'))
     self.assertRaises(IOError, self.metadata._delete_exif_tag,
                       'Exif.Image.Make')
     self.assertRaises(IOError, self.metadata._delete_iptc_tag,
                       'Iptc.Application2.Caption')
     self.assertRaises(IOError, self.metadata._delete_xmp_tag,
                       'Xmp.dc.format')
     self.assertRaises(IOError, getattr, self.metadata, 'comment')
     self.assertRaises(IOError, setattr, self.metadata, 'comment', 'foobar')
     self.assertRaises(IOError, delattr, self.metadata, 'comment')
     self.assertRaises(IOError, getattr, self.metadata, 'previews')
     other = ImageMetadata(self.pathname)
     self.assertRaises(IOError, self.metadata.copy, other)
     self.assertRaises(IOError, getattr, self.metadata, 'buffer')
     thumb = self.metadata.exif_thumbnail
     self.assertRaises(IOError, getattr, thumb, 'mime_type')
     self.assertRaises(IOError, getattr, thumb, 'extension')
     self.assertRaises(IOError, thumb.write_to_file, '/tmp/foobar.jpg')
     self.assertRaises(IOError, thumb.erase)
     self.assertRaises(IOError, thumb.set_from_file, '/tmp/foobar.jpg')
     self.assertRaises(IOError, getattr, thumb, 'data')
     self.assertRaises(IOError, setattr, thumb, 'data', EMPTY_JPG_DATA)
     self.assertRaises(IOError, getattr, self.metadata, 'iptc_charset')
Exemplo n.º 16
0
 def read_metadata(path, photo, prefix="orig_"):
     photo[prefix + "orientation"] = 1
     photo[prefix + "original_orientation"] = 1
     try:
         meta = ImageMetadata(path)
         meta.read()
         try:
             photo[prefix + "orientation"] = meta[
                 "Exif.Image.Orientation"].value
             photo[prefix + "original_orientation"] = meta[
                 "Exif.Image.Orientation"].value
         except KeyError:
             print
             _log.debug("Failed to read the orientation from %s" %
                        path)
         exposure_dt = meta["Exif.Image.DateTime"].value
         photo[prefix +
               "exposure_time"] = exif_datetime_to_time(exposure_dt)
     except KeyError:
         pass
     except Exception:
         print
         _log.exception("Failed to read date from %s", path)
         raise
Exemplo n.º 17
0
def test_read_nonexistent_file(empty_directory):
    non_jpg = os.path.join(empty_directory, 'non.jpg')
    m = ImageMetadata(non_jpg)
    with pytest.raises(OSError):
        m.read()
Exemplo n.º 18
0
def metadata_ro(jpg_with_tags):
    """A fresh *read-only* ImageMetadata object for the jpg_with_tags.
       Returns a 2-tuple (pathname, ImageMetadata).
       read() has not yet been called.  write() will fail.
    """
    return MetadataWithPath(jpg_with_tags, ImageMetadata(jpg_with_tags))
Exemplo n.º 19
0
def get_metadata():
    data = ImageMetadata(COPY)
    data.read()
    return data
Exemplo n.º 20
0
#
# Author: Olivier Tilloy <*****@*****.**>
#
# ******************************************************************************

import sys

from pyexiv2.metadata import ImageMetadata


if __name__ == '__main__':
    args = sys.argv

    if len(args) != 2:
        print 'Usage: %s image_file' % args[0]
        sys.exit(-1)

    metadata = ImageMetadata(args[1])
    metadata.read()

    for key in metadata.exif_keys:
        tag = metadata[key]
        print '%-45s%-11s%s' % (key, tag.type, str(tag))

    for key in metadata.iptc_keys:
        tag = metadata[key]
        print '%-45s%-11s%s' % (key, tag.type, str(tag))

    # TODO: print XMP tags.

Exemplo n.º 21
0
 def test_read_nonexistent_file(self):
     metadata = ImageMetadata('idontexist')
     self.failUnlessRaises(IOError, metadata.read)
Exemplo n.º 22
0
 def _test_filename(self, filename):
     self._create_file(filename)
     m = ImageMetadata(filename)
     m.read()
     os.remove(filename)