From fa36fad62d6f024941979b8f1db3c464b038d342 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Fri, 21 May 2010 19:52:35 +0200 Subject: Get, set and delete the image comment. --- src/exiv2wrapper.cpp | 19 +++++++++++++++++++ src/exiv2wrapper.hpp | 5 +++++ src/exiv2wrapper_python.cpp | 4 ++++ src/pyexiv2/metadata.py | 15 +++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/src/exiv2wrapper.cpp b/src/exiv2wrapper.cpp index d8ee8e5..c64c0fe 100644 --- a/src/exiv2wrapper.cpp +++ b/src/exiv2wrapper.cpp @@ -343,6 +343,25 @@ void Image::deleteXmpTag(std::string key) throw Exiv2::Error(KEY_NOT_FOUND, key); } +const std::string Image::getComment() const +{ + CHECK_METADATA_READ + return _image->comment(); +} + +void Image::setComment(const std::string& comment) +{ + CHECK_METADATA_READ + _image->setComment(comment); +} + +void Image::clearComment() +{ + CHECK_METADATA_READ + _image->clearComment(); +} + + boost::python::list Image::previews() { CHECK_METADATA_READ diff --git a/src/exiv2wrapper.hpp b/src/exiv2wrapper.hpp index d929f8b..53a0de2 100644 --- a/src/exiv2wrapper.hpp +++ b/src/exiv2wrapper.hpp @@ -222,6 +222,11 @@ public: // Throw an exception if the tag was not set. void deleteXmpTag(std::string key); + // Comment + const std::string getComment() const; + void setComment(const std::string& comment); + void clearComment(); + // Read access to the thumbnail embedded in the image. boost::python::list previews(); diff --git a/src/exiv2wrapper_python.cpp b/src/exiv2wrapper_python.cpp index e5855c4..441578f 100644 --- a/src/exiv2wrapper_python.cpp +++ b/src/exiv2wrapper_python.cpp @@ -130,6 +130,10 @@ BOOST_PYTHON_MODULE(libexiv2python) .def("_getXmpTag", &Image::getXmpTag) .def("_deleteXmpTag", &Image::deleteXmpTag) + .def("_getComment", &Image::getComment) + .def("_setComment", &Image::setComment) + .def("_clearComment", &Image::clearComment) + .def("_previews", &Image::previews) .def("_copyMetadata", &Image::copyMetadata) diff --git a/src/pyexiv2/metadata.py b/src/pyexiv2/metadata.py index c275a9d..69822bf 100644 --- a/src/pyexiv2/metadata.py +++ b/src/pyexiv2/metadata.py @@ -296,6 +296,21 @@ class ImageMetadata(object): except AttributeError: raise KeyError(key) + def _get_comment(self): + return self._image._getComment() + + def _set_comment(self, comment): + if comment is not None: + self._image._setComment(comment) + else: + self._del_comment() + + def _del_comment(self): + self._image._clearComment() + + comment = property(fget=_get_comment, fset=_set_comment, fdel=_del_comment, + doc='The image comment.') + @property def previews(self): """List of the previews available in the image, sorted by increasing -- cgit From 0ca273f88840e64510b0ed2cd2edcff3ccc05aea Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Fri, 21 May 2010 19:55:19 +0200 Subject: Include the image comment in the API documentation. --- doc/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api.rst b/doc/api.rst index e373487..de6c918 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -17,7 +17,7 @@ pyexiv2.metadata .. autoclass:: ImageMetadata :members: from_buffer, read, write, dimensions, mime_type, exif_keys, iptc_keys, xmp_keys, __getitem__, __setitem__, __delitem__, - previews, copy, buffer + comment, previews, copy, buffer pyexiv2.exif ############ -- cgit From 550dc9ae815cc012a9c8cd755ddb58c496a3a13c Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Fri, 21 May 2010 20:04:23 +0200 Subject: Copy the image comment when copying all the metadata from one image to the other. --- src/pyexiv2/metadata.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pyexiv2/metadata.py b/src/pyexiv2/metadata.py index 69822bf..22eb4a9 100644 --- a/src/pyexiv2/metadata.py +++ b/src/pyexiv2/metadata.py @@ -317,7 +317,7 @@ class ImageMetadata(object): size.""" return [Preview(preview) for preview in self._image._previews()] - def copy(self, other, exif=True, iptc=True, xmp=True): + def copy(self, other, exif=True, iptc=True, xmp=True, comment=True): """ Copy the metadata to another image. The metadata in the destination is overridden. In particular, if the @@ -333,6 +333,8 @@ class ImageMetadata(object): :type iptc: boolean :param xmp: whether to copy the XMP metadata :type xmp: boolean + :param comment: whether to copy the image comment + :type comment: boolean """ self._image._copyMetadata(other._image, exif, iptc, xmp) # Empty the cache where needed @@ -345,6 +347,8 @@ class ImageMetadata(object): if xmp: other._keys['xmp'] = None other._tags['xmp'] = {} + if comment: + other.comment = self.comment @property def buffer(self): -- cgit From f33e97cce19571f9470787c56541800eeb87f6e6 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Fri, 21 May 2010 20:30:58 +0200 Subject: Unit tests: use a JPEG image instead of a PNG image. It looks like exiv2 (silently) fails to set the comment on an empty PNG image. Needs further investigation. --- test/metadata.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/test/metadata.py b/test/metadata.py index 86935ce..a501c8c 100644 --- a/test/metadata.py +++ b/test/metadata.py @@ -36,18 +36,31 @@ import tempfile import unittest -EMPTY_PNG_DATA = \ - '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08' \ - '\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDATx\x9cc```\x00\x00\x00\x04' \ - '\x00\x01\xf6\x178U\x00\x00\x00\x00IEND\xaeB`\x82' +EMPTY_JPG_DATA = \ + '\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xdb' \ + '\x00C\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ + '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ + '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ + '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x0b\x08' \ + '\x00\x01\x00\x01\x01\x01\x11\x00\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01' \ + '\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06' \ + '\x07\x08\t\n\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05' \ + '\x05\x04\x04\x00\x00\x01}\x01\x02\x03\x00\x04\x11\x05\x12!1A\x06\x13Qa' \ + '\x07"q\x142\x81\x91\xa1\x08#B\xb1\xc1\x15R\xd1\xf0$3br\x82\t\n\x16\x17' \ + "\x18\x19\x1a%&\'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x83\x84\x85" \ + '\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5' \ + '\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5' \ + '\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4' \ + '\xe5\xe6\xe7\xe8\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xda' \ + '\x00\x08\x01\x01\x00\x00?\x00\x92\xbf\xff\xd9' class TestImageMetadata(unittest.TestCase): def setUp(self): # Create an empty image file - fd, self.pathname = tempfile.mkstemp(suffix='.png') - os.write(fd, EMPTY_PNG_DATA) + fd, self.pathname = tempfile.mkstemp(suffix='.jpg') + os.write(fd, EMPTY_JPG_DATA) os.close(fd) # Write some metadata m = ImageMetadata(self.pathname) @@ -482,7 +495,7 @@ class TestImageMetadata(unittest.TestCase): #################### def _set_up_other(self): - self.other = ImageMetadata.from_buffer(EMPTY_PNG_DATA) + self.other = ImageMetadata.from_buffer(EMPTY_JPG_DATA) def test_copy_metadata(self): self.metadata.read() -- cgit From 59797a333d118cf12ba5d16a89993e5e85938f18 Mon Sep 17 00:00:00 2001 From: Olivier Tilloy Date: Fri, 21 May 2010 20:31:42 +0200 Subject: Unit tests for the image comment. --- test/metadata.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/metadata.py b/test/metadata.py index a501c8c..98be0be 100644 --- a/test/metadata.py +++ b/test/metadata.py @@ -71,6 +71,7 @@ class TestImageMetadata(unittest.TestCase): 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) @@ -490,6 +491,27 @@ class TestImageMetadata(unittest.TestCase): for key in keys: self.failUnlessRaises(KeyError, self.metadata.__delitem__, key) + ########################## + # Test the image comment # + ########################## + + def test_get_comment(self): + self.metadata.read() + self.failUnlessEqual(self.metadata.comment, 'Hello World!') + + def test_set_comment(self): + self.metadata.read() + comment = 'Welcome to the real world.' + self.metadata.comment = comment + self.failUnlessEqual(self.metadata.comment, comment) + self.metadata.comment = None + self.failUnlessEqual(self.metadata.comment, '') + + def test_delete_comment(self): + self.metadata.read() + del self.metadata.comment + self.failUnlessEqual(self.metadata.comment, '') + #################### # Test metadata copy #################### @@ -524,3 +546,5 @@ class TestImageMetadata(unittest.TestCase): for key in self.metadata.xmp_keys: self.failUnlessEqual(self.metadata[key].value, self.other[key].value) + self.failUnlessEqual(self.metadata.comment, self.other.comment) + -- cgit