Code Monkey home page Code Monkey logo

pyexiv2's Introduction

pyexiv2

Read and write image metadata, including EXIF, IPTC, XMP, ICC Profile.

Features

Defects

  • Can't read the image larger than 2GB, or modify the image larger than 1GB. (related issue)
  • Not thread safe, because pyexiv2 uses some global variables in C++.
  • Currently, if you use ARM platform, you need to compile exiv2 and pyexiv2 manually, which is troublesome. (related issue)

Tests

There are some test cases in folder pyexiv2/tests.

References

  • Similar projects:

    • exiv2 is a C++ library for reading and writing various image metadata, including command-line tools.
    • pyexiv2 is a Python2 binding to exiv2, hasn't been updated since 2011.
    • py3exiv2 is a Python3 binding to exiv2, wrapped with Boost.Python.
    • python-exiv2 is a Python3 binding to exiv2, wrapped with SWIG. The intention is to give direct access to all of the top-level classes in exiv2.
    • exiftool is a perl library for reading and writing various image metadata, including command-line tools.
  • Books:

pyexiv2's People

Contributors

auphofbsf avatar dgtlmoon avatar jim-easterbrook avatar leohsiao1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pyexiv2's Issues

error while installing pyexiv2

Collecting pyexiv2
Using cached pyexiv2-2.3.1.tar.gz (4.0 MB)
ERROR: Command errored out with exit status 1:
command: /usr/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-Osypvi/pyexiv2/setup.py'"'"'; file='"'"'/tmp/pip-install-Osypvi/pyexiv2/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-XnkqaZ
cwd: /tmp/pip-install-Osypvi/pyexiv2/
Complete output (5 lines):
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-Osypvi/pyexiv2/setup.py", line 4, in
with open('README.md', encoding='utf-8') as f:
TypeError: 'encoding' is an invalid keyword argument for this function
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Support CR3 files via Exix 0.27.4RC

I don't know if this is the right place to ask but currently I don't see a possibility to make use of the new features introduced by 0.27.4 (RC,2,3) which I am running on my system. Will this be possible as soon as the GM release happens or if this is not the place to ask, where should I go or if one can help, what needs to be done to support this feature?

problem in puthon 2 with open and encoding keyword

In setup.py open is called with keywork "encoding" (line 4)
this don't work in python 2, hence sugest to "import io" and use "io.open" insted.

eg. see this:
https://stackoverflow.com/questions/25049962/is-encoding-is-an-invalid-keyword-error-inevitable-in-python-2-x

Error from pip instal:
(base) C:\Users\MartinHuusBjerge>pip install pyexiv2
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Collecting pyexiv2
Using cached https://files.pythonhosted.org/packages/c4/f0/acd45defbb3dd1147f47837ce06f27b3d7978a3fc47d24556cf630bbccd0/pyexiv2-1.3.0.tar.gz
ERROR: Command errored out with exit status 1:
command: 'c:\programdata\anaconda2\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'c:\users\martin1\appdata\local\temp\pip-install-wgew3s\pyexiv2\setup.py'"'"'; file='"'"'c:\users\martin1\appdata\local\temp\pip-install-wgew3s\pyexiv2\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base 'c:\users\martin1\appdata\local\temp\pip-install-wgew3s\pyexiv2\pip-egg-info'
cwd: c:\users\martin
1\appdata\local\temp\pip-install-wgew3s\pyexiv2
Complete output (5 lines):
Traceback (most recent call last):
File "", line 1, in
File "c:\users\martin~1\appdata\local\temp\pip-install-wgew3s\pyexiv2\setup.py", line 4, in
with open("README.md", encoding="utf-8") as f:
TypeError: 'encoding' is an invalid keyword argument for this function
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Cannot open DNG files

traceback:

Traceback (most recent call last):
File "/home/ermesa/Programming Projects/python/photo_stats/photostats/lenses.py", line 66, in
test_exif = get_exif.get_exif(test_photos)
File "/home/ermesa/Programming Projects/python/photo_stats/photostats/get_exif.py", line 44, in get_exif
this_image = Image(image)
File "/home/ermesa/Programming Projects/python/photo_stats/venv/lib64/python3.7/site-packages/pyexiv2/core.py", line 16, in init
self.img = api.open_image(filename.encode(encoding))
RuntimeError: Directory Canon with 25665 entries considered invalid; not read.

file: https://www.dropbox.com/s/c1i96a743mx0svj/Canon%20EOS%20Rebel%20XT.dng?dl=0

Directory Canon with 7424 entries considered invalid; not read.

My code:

# Mac bigsur, Python3.7.6
from pyexiv2 import Image

img = Image(r'IMG_9699.jpg')
img.read_exif()

Error:

Traceback (most recent call last):

  File "/Users/***/Desktop/exiv2_test/pyexiv2-master/sample.py", line 3, in <module>
    img = Image(r'IMG_9699.jpg')
  File "/Users/***/Desktop/exiv2_test/pyexiv2-master/pyexiv2/core.py", line 16, in __init__
    self.img = exiv2api.Image(filename.encode(encoding))
RuntimeError: Directory Canon with 7424 entries considered invalid; not read.

With exiv2 command line tool, it returns error and metadata.
e

I am sorry I cannot attach the jpg file due to the copyright issue.
Is it possible to ignore the error and get the metadata?
Thank you.

read_exif twice or to dict will crash pyexiv2

Hi!

I encounter a problem with pyexiv2: the following will work fine:

Python 3.7.3 (default, Apr  4 2019, 08:55:10) 
[GCC 8.3.1 20190329] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyexiv2            
>>> image = pyexiv2.Image('image.jpg')
>>> image.read_exif()
{'Exif.Image.Make': 'Panasonic', 'Exif.Image.Model': 'DMC-FZ1000', ...

But calling read_exif a second time or saving output to a dict will produce:

>>> image.read_exif()
corrupted size vs. prev_size
Abandon (core dumped)
>>> exif = image.read_exif()
corrupted size vs. prev_size
Abandon (core dumped)

What can I do? Thanks in advance! Best regards

Cannot read/write image in a folder with cyrillic name, on windows

The library cannot read/write the image from folder that contain cyrillic symbols, on windows, however on Linux it works very well.

Example little thing:

# read
image_path = "C:\Users\TheUser\Desktop\test\тест призначення\electromecánico\good bike.JPG"
img = pyexiv2.Image(image_path)
metadata = img.read_xmp()
print(metadata)

# write
keywords = ["foo", "bar"]
new_meta = {'Xmp.dc.subject': keywords}
img.modify_xmp(new_meta)

Produce error Failed to open the data source: No such file or directory (errno = 2)

Traceback:

Traceback (most recent call last):
  File "C:\py-dev\test-meta\edit-xmp.py", line 15
    img = pyexiv2.Image(image_path)
  File "C:\py-dev\test-meta\env\lib\site-packages\pyexiv2\core.py", line 16, in __init__
    self.img = api.open_image(filename.encode(encoding))
RuntimeError: C:\Users\TheUser\Desktop\test\тест призначення\electromecánico\good bike.JPG: Failed to open the data source: No such file or directory (errno = 2)

api.open_image() does not see the file in some reason.
If use path without cyrillic symbols then all works.

"encoding" keyword does not exist?

Hi, and thanks for the nice tool!

I am now faced with filenames containing German umlauts, which are not readable by pyexiv2.Image(path).read_exif() due to the umlaut, I assume:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa8 in position 97: invalid start byte

Following the tutorial, I tried pyexiv2.Image(path, encoding='ISO-8859-1'), which raises the exception:

TypeError: init() got an unexpected keyword argument 'encoding'

The filename contains the umlaut ü (albeit at position 73; the filename is only 90 characters long). Without this character, metadata loads fine.

I'm running Python 3.8 on Windows 8.1, just downloaded then newest version of pyexiv2.

Get human-readable EXIF tag description

I'm looking for some Python EXIF solution that can handle "MakerNote", so I had to find some exiv2-based solution, one of them is yours.

Is it possible to get the "tag description" via the exiv2 library and your wrapper?
Example: https://www.exiv2.org/tags-canon.html. I can get Exif.Canon.ShotInfo but I also want the string Shot information which is from the "tag description" column.

exiv2 seems to support it:
https://github.com/Exiv2/exiv2/blob/master/src/canonmn_int.cpp#L427
With probably this:
https://github.com/Exiv2/exiv2/blob/master/include/exiv2/tags.hpp#L207 (tagDesc)

Thank you

from pyexiv2 import Image

Traceback (most recent call last):
File "", line 1007, in _find_and_load
File "", line 986, in _find_and_load_unlocked
File "", line 680, in _load_unlocked
File "", line 855, in exec_module
File "", line 228, in _call_with_frames_removed
File "/opt/homebrew/lib/python3.9/site-packages/pyexiv2/init.py", line 6, in
from .core import *
File "/opt/homebrew/lib/python3.9/site-packages/pyexiv2/core.py", line 1, in
from .lib import exiv2api
File "/opt/homebrew/lib/python3.9/site-packages/pyexiv2/lib/init.py", line 25, in
ctypes.CDLL(os.path.join(lib_dir, 'libexiv2.dylib'))
File "/opt/homebrew/Cellar/[email protected]/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ctypes/init.py", line 374, in init
self._handle = _dlopen(self._name, mode)
OSError: dlopen(/opt/homebrew/lib/python3.9/site-packages/pyexiv2/lib/libexiv2.dylib, 6): image not found

Uncatchable error thrown by exiv2

Bug description:
While reading some of my images, i get the following error printed to console:

Error: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 31578, exceeds buffer size by 76 Bytes; truncating the entry

This error seems to be thrown by exiv2 but is not translated into a catchable python error.

Expected behaviour:
The error should be catchable.
A UpperBoundaryError extending Exception should be thrown.
The following code should be able to catch this error.

try:
    exif = im.read_exif() # where img is a valid pyexiv2.Image object
except BaseException as e:
    print(e)

What i found so far:
I traced the error down to the following function in core.py:

    def _open_image(self):
        """ Let C++ program open an image and read its metadata,
        save as a global variable in C++ program. """
        api.open_image.restype = ctypes.c_char_p
        ret = api.open_image(
            self.filename).decode()  # WIP: "Error: Upper boundary of data (...)" seems to originate here.
        if ret != OK:
            raise RuntimeError(ret)

Edit
Added new findings.

Unable to read exift data!

Hi, I have a problem with reading the exif and iptc data from *.png files.
When I use Exiftool, I can see that the information is there, however when I use pyexiv2 my exif/iptc data dictionaries are empty, it only happens with png files, for the rest (jpg,tiff,) it works.

Xmp LangAlt handling

At present Xmp data with 'LangAlt' type is presented as a string with the languages included, such as lang="x-default" Hello, world, lang="de-DE" Hallo, Welt. This is not very easy to use, and easy to get wrong when setting a value. Would it be better to use a dict for this, e.g. {'x-default': 'Hello, world', 'de-DE': 'Hallo, Welt'}.

exif date string format stable?

hi there, thanks for your work on pyexiv2.

the various date-times in exif info returned by pyexiv2 seem to always be in this format: '2019:06:23 19:45:17'
is this a guaranteed date-time format for the exif returned?

i ask because i need to create datetime.datetime objects from these returned exif dates and using datetime.datetime.strptime() relies on a known format for the date-time string.

thanks.

Copying data to new image, the xmp size in bytes is different

Hi,

I tried to create a new image and copy the metadata from this image to one I created using PIL. For some reason when checking the bytes of the xmp-profile with the identify tool by ImageMagiC I get a different size although the value of the tags seem to be the same.

Do you have some explenation for why this happens?

Core dumped when exiting pyexiv2

I'm getting various memory allocation related errors when exiting pyexiv2 -- even if I'm just importing it and then immediately exiting. To be clear, everything works just fine, it's just that there's this annoying un-catchable error at the end.

Here's a minimal example:

$ python3 -c "import pyexiv2"
free(): invalid pointer
Aborted (core dumped)
$
$ uname -a
Linux A190311601-1903 4.4.0-17763-Microsoft #253-Microsoft Mon Dec 31 17:49:00 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
$
$ pip3 show pyexiv2
Name: pyexiv2
Version: 2.1.0
Summary: Read/Write metadata of digital image, including EXIF, IPTC, XMP.
Home-page: https://github.com/LeoHsiao1/pyexiv2
Author: LeoHsiao
Author-email: [email protected]
License: UNKNOWN
Location: /home/toaarnio/.local/lib/python3.6/site-packages
Requires:
Required-by:

I'm running Ubuntu 18.04.4 LTS under Windows 10.

modify_xmp() does not properly change tags

I use modify_xmp() to replace the tags on an image.
Then I use read_xmp() to check the results. As expected, the image has the new set of tags.
Now I check the properties of the file by right clicking on the file in windows explorer.
However, the old tags are still there.
The tags as reported by read_xmp() are now incorrect.

GLIBC Version 2.29

The new version 2.6 has been giving me this error with my dockerfile (based on python3.8.5-slim) which natively runs version glibc version 2.28.

oserror: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /usr/local/lib/python3.8/site-packages/pyexiv2/lib/libexiv2.so)

Going back to version 2.5.0 fixed the issue for me.

Just letting you know that issue exists ;)

clear_exif() / clear_iptc() / clear_xmp() not clearing Comment field

ab95627d37e9f9baecea24ee52b6377e

        exiv_image = pyexiv2.Image(filepath)
        exiv_image.clear_exif()
        exiv_image.clear_iptc()
        exiv_image.clear_xmp()

then I look at the file with exiftool

ExifTool Version Number         : 11.16
File Name                       : ab95627d37e9f9baecea24ee52b6377e.jpg
Directory                       : /var/www/tshirtslayer/web/files-tshirt/styles/shirtview/public/user-11635
File Size                       : 35 kB
File Modification Date/Time     : 2020:12:25 21:13:06+00:00
File Access Date/Time           : 2016:01:15 06:02:14+00:00
File Inode Change Date/Time     : 2020:12:25 21:13:06+00:00
File Permissions                : rw-rw-r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
JFIF Version                    : 1.01
Resolution Unit                 : inches
X Resolution                    : 96
Y Resolution                    : 96
Comment                         : CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 80.
Image Width                     : 856
Image Height                    : 482
Encoding Process                : Baseline DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:2:0 (2 2)
Image Size                      : 856x482
Megapixels                      : 0.413

I was hoping that

Comment : CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 80.

would be gone

I'm also unable to override that with

            exiv_image.modify_exif({'Exif.Image.DocumentName': description,
                                    'Exif.Image.ImageDescription': description,
                                    'Exif.Photo.UserComment': description,
                                    'Exif.Image.Copyright' : "Copyright Creative Commons 3.0",
                                    'Exif.Image.DateTime': exif_date,
                                    'Exif.Image.DateTimeOriginal' : exif_date,
                                    'Exif.Photo.DateTimeDigitized' : exif_date,
                                    }
                                   )

ideas? file attached

read_xmp Crashes python without exception

A very good little module that works well but is crashing python on a read_xmp with a .jpg file straight from Digikam. However periodically it runs through successfully on this file. It appears totally random as to which rerun it will work on.
No Exception is raised, python just terminates.....
This feels similar to the #2 raised and closed

Environment details below and jpg exhibiting issue is attached.
Note. The modify_xmp() is commented out to not alter the jpg for debugging the read_xmp

from pyexiv2 import Image
imageFile = r"D:\tmp\19W38\pyexiv2\pyexiv2ISSUE19w38d1aMod2.jpg"
image = Image(imageFile)
xmpDict = image.read_xmp()

print('Image xmp was succesfully read -----------------')
print(xmpDict['Xmp.digiKam.TagsList'])
print(xmpDict['Xmp.dc.subject'])

xmpDictNew = xmpDict.copy()
xmpDictNew['Xmp.dc.subject'] = xmpDict['Xmp.digiKam.TagsList']
#image.modify_xmp(xmpDictNew)

The jpg exhibiting this issue is in a branch of my fork. auphofBSF@3890a83

Environment is Windows 10
Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 16:05:27) [MSC v.1900 64 bit (AMD64)] on win32
pyexiv2 commit e78a78a Date: Fri Sep 6 20:37:58 2019 +0800 updated test cases

Not exactly sure how to debug the api but have successfully rebuilt api.dll under exiv2 https://github.com/Exiv2/exiv2/releases/tag/v0.27.2 without success of fixing.

I have further additional instructions for building under VS2017 which I can raise as an additional pull request, I was unable to build under VS2015

working together with pillow?

Hi Leo,

thanks for a wonderful module and maintaining it!

Is there a way that I can open an image from pillow directly without writing it to the disk first?

Thanks!

Unable to read HEIC file

Hi, I'm trying to read EXIF for different types of photos and jpg have no problem at all. But when comes to HEIC it says unknown image type. I did went to exiv2 release notes and v0.27.4 says supported HEIC. Any suggestion? Thanks!

self.img = exiv2api.Image(filename.encode(encoding)) RuntimeError: C:\test11\IMG_0005_20180212133649.heic: The file contains data of an unknown image type

Python: 3.9
pyexiv2: 2.6.0
OS: Win 10

[WinError 193] %1 is not a valid Win32 application

When i run "from pyexiv2 import Image" command, python throw an exception:

File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyexiv2_init_.py", line 7, in
from .core import Image
File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyexiv2\core.py", line 22, in
ctypes.CDLL(os.path.join(dll_dir, "exiv2.dll"))
File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\ctypes_init_.py", line 369, in init
self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

How can I set a list as dc.subject?

I tried setting a list, but it wouldn't accept that saying it requires a string. A comma separated string will just render a string, though, which doesn't get picked up by other software as a list.

Appreciate your help :)

iptc.get() return a string in some cases

Thanks for this amazing package!

I’m having a minor issue when reading the IPTC tags (or keywords) of an image, using the following code:

img = pyexiv2.Image(localFile)
iptc = img.read_iptc()
iptc_tags = iptc.get('Iptc.Application2.Keywords') or list()
iptc_tags.append('a new tag')

If the image doesn’t have tags, or if it has multiple tags then the code works fine.

However, if the image has exactly 1 tag, then iptc.get('Iptc.Application2.Keywords') returns a string instead of list.

Is there an option to have iptc.get() always return a list?

OSError: /lib64/libm.so.6: version `GLIBC_2.27' not found

Traceback (most recent call last):
File "/home/py/PycharmProjects/SphinxDoc/_test/md_album.py", line 283, in
from pyexiv2 import Image
File "/home/py/anaconda3/envs/py35/lib/python3.5/site-packages/pyexiv2/init.py", line 6, in
from .core import *
File "/home/py/anaconda3/envs/py35/lib/python3.5/site-packages/pyexiv2/core.py", line 2, in
from .lib import exiv2api as api
File "/home/py/anaconda3/envs/py35/lib/python3.5/site-packages/pyexiv2/lib/init.py", line 19, in
ctypes.CDLL(os.path.join(lib_dir, 'libexiv2.so')) # import the library at first, otherwise the Python interpreter can not find it.
File "/home/py/anaconda3/envs/py35/lib/python3.5/ctypes/init.py", line 351, in init
self._handle = _dlopen(self._name, mode)
OSError: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /home/py/anaconda3/envs/py35/lib/python3.5/site-packages/pyexiv2/lib/libexiv2.so)

libexiv2.dylib missing in PyPI package

Hi,

I tried using pyexiv2 recently in a conda environment with Python 3.7.4 on macOS 10.15.4, and it seems there is a libexiv2.dylib missing from the package.

(base) jusic@jussis-mbp  % pip install pyexiv2
Collecting pyexiv2
  Downloading https://files.pythonhosted.org/packages/87/ff/9d8b88a731b463b7ff4e6b10c83069ff131ab359ec9c7491bb63c70a55a9/pyexiv2-2.3.0-py3-none-any.whl (3.1MB)
     |████████████████████████████████| 3.1MB 6.0MB/s
Installing collected packages: pyexiv2
Successfully installed pyexiv2-2.3.0
(base) jusic@jussis-mbp % python
Python 3.7.4 (default, Aug 13 2019, 15:17:50)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyexiv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/jusic/anaconda3/lib/python3.7/site-packages/pyexiv2/__init__.py", line 6, in <module>
    from .core import *
  File "/Users/jusic/anaconda3/lib/python3.7/site-packages/pyexiv2/core.py", line 2, in <module>
    from .lib import exiv2api
  File "/Users/jusic/anaconda3/lib/python3.7/site-packages/pyexiv2/lib/__init__.py", line 23, in <module>
    ctypes.CDLL(os.path.join(lib_dir, 'libexiv2.dylib'))
  File "/Users/jusic/anaconda3/lib/python3.7/ctypes/__init__.py", line 364, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/Users/jusic/anaconda3/lib/python3.7/site-packages/pyexiv2/lib/libexiv2.dylib, 6): image not found

If I separately brew install pyexiv2 and then copy the dylib manually, it at least loads properly:

(base) jusic@jussis-mbp % cp /usr/local/Cellar/exiv2/0.27.3/lib/libexiv2*.dylib /Users/jusic/anaconda3/lib/python3.7/site-packages/pyexiv2/lib/
(base) jusic@jussis-mbp % python
Python 3.7.4 (default, Aug 13 2019, 15:17:50)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyexiv2
>>>

Would it be possible to get the dylib packaged as well in the PyPI package?

Incorrect values after modify_xmp

I'm trying to modify the ToneCurve values of an image.

These are the original:
{'Xmp.crs.ToneCurveName2012': 'Linear',
'Xmp.crs.ToneCurvePV2012': ['0', '0', '255', '255'],
'Xmp.crs.ToneCurvePV2012Red': ['0', '0', '255', '255'],
'Xmp.crs.ToneCurvePV2012Green': ['0', '0', '255', '255'],
'Xmp.crs.ToneCurvePV2012Blue': ['0', '0', '255', '255']}

These are the ones I want to set:
{'Xmp.crs.ToneCurveName2012': 'Custom',
'Xmp.crs.ToneCurvePV2012': ['0', '11', '32', '25', '67', '74', '114', '131', '176', '181', '252', '230'],
'Xmp.crs.ToneCurvePV2012Red': ['0', '0', '54', '37', '183', '196', '255', '255'],
'Xmp.crs.ToneCurvePV2012Green': ['0', '0', '68', '49', '173', '185', '255', '255'],
'Xmp.crs.ToneCurvePV2012Blue': ['0', '0', '65', '48', '190', '203', '255', '255']}

This is what I end up with after using modify_xmp:
{'Xmp.crs.ToneCurveName2012': 'Custom',
'Xmp.crs.ToneCurvePV2012': '230',
'Xmp.crs.ToneCurvePV2012Red': '255',
'Xmp.crs.ToneCurvePV2012Green': '255',
'Xmp.crs.ToneCurvePV2012Blue': '255'}

It seems to only be getting the last value from the modified dict's lists.

PyPi *Source* and Wheel Distributions Contain Architecture-Specific Binaries and Possible GPLv2 License Violation

Hello!

Both the source and binary wheel distributions of pyexiv2 (as of v2.3.1 as hosted on PyPi) contain binaries compiled for x86-64. When installing on aarch64, for example, the package is completely broken.

Couple of things:

  1. Source distributions should never contain binaries - that's the whole point of source distributions... even for external libraries.
  2. Binary wheels with the "none-any" platform tag are not expected to contain architecture dependent code .... e.g. pyexiv2-2.3.1-py3-none-any.whl would be an architecture independent wheel. It's perfectly fine to have pre-compiled binaries in a binary wheel but they need to be properly tagged. See https://packaging.python.org/specifications/platform-compatibility-tags/
  3. Not using the binary packaging guidance has resulted in unnecessary bloat in the form of including extraneous files that are unneeded for the current OS, current architecture, and current python version. The Packaging standards were designed to (mostly) address this. That's why there are tags for different OSes, Architectures, and Python Versions. The directory listing below shows 11MiB installed - when at most it should be ~2.8mb per platform.
.
├── [211K]  darwin64-py35
│   └── [207K]  exiv2api.so
├── [211K]  darwin64-py36
│   └── [207K]  exiv2api.so
├── [211K]  darwin64-py37
│   └── [207K]  exiv2api.so
├── [212K]  darwin64-py38
│   └── [208K]  exiv2api.so
├── [2.6M]  exiv2.dll
├── [2.6M]  libexiv2.dylib
├── [3.4M]  libexiv2.so
├── [221K]  linux64-py35
│   └── [217K]  exiv2api.so
├── [221K]  linux64-py36
│   └── [217K]  exiv2api.so
├── [222K]  linux64-py37
│   └── [218K]  exiv2api.so
├── [215K]  linux64-py38
│   └── [211K]  exiv2api.so
├── [299K]  win64-py35
│   └── [295K]  exiv2api.pyd
├── [299K]  win64-py36
│   └── [295K]  exiv2api.pyd
├── [300K]  win64-py37
│   └── [296K]  exiv2api.pyd
└── [304K]  win64-py38
    └── [300K]  exiv2api.pyd

11M used in 12 directories, 15 files

Possible GPLv2 License Violation of exiv2

Exiv2 is released under the GPLv2 -- which AFAIK requires that if you distribute binaries, you must make the source code available for those binaries. Further, this is the right thing to do on many fronts. Check out: https://reproducible-builds.org

Further, read GNU's GPL guidance on this very topic here: https://www.gnu.org/licenses/gpl-faq.html#UnchangedJustBinary

Making binaries is fine - but you have to release the source. Since exiv2 is already on github ... adding it as a git submodule and then having python build the dependency would be the best option. That way, if someone downloads the package on a different architecture, they will be able to build it too 😁

References

https://www.python.org/dev/peps/pep-0425/

RuntimeError('Memory allocation failed') on appending XMP tags to large JPEG's.

Hi! I'm using Pyexiv2 to write XMP tags to a large JPEG file - 1.5gb, 61328 x 61535 pixels. Since the file limit is 2gb this should work. However, I am hitting RuntimeError('Memory allocation failed'). The same image at lower resolution work with the same tages.

The piece of code is simple enough:

    final_image_filename = outfile or (info.image_name + '.jpg')
    img.save(final_image_filename, quality=quality, subsampling=0) ##PIL saving
    dir_path = os.path.dirname(os.path.realpath(__file__)) + '\\' + final_image_filename ##Passing the file 
    print(dir_path)

    for key, value in info.metadata.items():
        try:
            xmp_file_obj.modify_xmp({key: value})
        except RuntimeError as e:
            print(f'Failed to add add XMP tag with key "{key}" with value "{value}"')
            print(repr(e))

Does Pyexiv2 have to open the image in memory in order to add tags to it? I'm not sure where it's gone wrong here.

Current master is failing build test on Ubuntu 18.0.4.5

Python3.6 on ubuntu here

git clone https://github.com/LeoHsiao1/pyexiv2.git
cd pyexiv2
cd pyexiv2/lib/
g++ exiv2api.cpp -o py36-linux/exiv2api.so -O3 -Wall -std=c++11 -shared -fPIC `python3 -m pybind11 --includes` -I /usr/include/exiv2 -I /usr/include/python3 -L ./lib -l exiv2
cd ../..
python3 setup.py install
pytest -v
pyexiv2/tests/test_func.py::test_read_exif PASSED                                                                                                                                                          [  3%]
pyexiv2/tests/test_func.py::test_read_iptc PASSED                                                                                                                                                          [  7%]
pyexiv2/tests/test_func.py::test_read_xmp PASSED                                                                                                                                                           [ 11%]
pyexiv2/tests/test_func.py::test_read_raw_xmp FAILED                                                                                                                                                       [ 15%]
pyexiv2/tests/test_func.py::test_modify_exif PASSED                                                                                                                                                        [ 19%]
pyexiv2/tests/test_func.py::test_modify_iptc PASSED                                                                                                                                                        [ 23%]
pyexiv2/tests/test_func.py::test_modify_xmp PASSED                                                                                                                                                         [ 26%]
pyexiv2/tests/test_func.py::test_clear_exif PASSED                                                                                                                                                         [ 30%]
pyexiv2/tests/test_func.py::test_clear_iptc PASSED                                                                                                                                                         [ 34%]
pyexiv2/tests/test_func.py::test_clear_xmp PASSED                                                                                                                                                          [ 38%]
pyexiv2/tests/test_func.py::test_nonexistent_path PASSED                                                                                                                                                   [ 42%]
pyexiv2/tests/test_func.py::test_not_image_path PASSED                                                                                                                                                     [ 46%]
pyexiv2/tests/test_func.py::test_error_log PASSED                                                                                                                                                          [ 50%]
pyexiv2/tests/test_func_on_ImageData.py::test_read_all FAILED                                                                                                                                              [ 53%]
pyexiv2/tests/test_func_on_ImageData.py::test_modify_exif PASSED                                                                                                                                           [ 57%]
pyexiv2/tests/test_func_on_ImageData.py::test_modify_iptc PASSED                                                                                                                                           [ 61%]
pyexiv2/tests/test_func_on_ImageData.py::test_modify_xmp PASSED                                                                                                                                            [ 65%]
pyexiv2/tests/test_func_on_ImageData.py::test_clear_all PASSED                                                                                                                                             [ 69%]
pyexiv2/tests/test_func_on_ImageData.py::test_error_log PASSED                                                                                                                                             [ 73%]
pyexiv2/tests/test_perf.py::test_memory_leak_when_reading FAILED                                                                                                                                           [ 76%]
pyexiv2/tests/test_perf.py::test_memory_leak_when_writing PASSED                                                                                                                                           [ 80%]
pyexiv2/tests/test_perf.py::test_stack_overflow PASSED                                                                                                                                                     [ 84%]
pyexiv2/tests/test_perf.py::test_transmit_various_characters PASSED                                                                                                                                        [ 88%]
pyexiv2/tests/test_perf_on_ImageData.py::test_memory_leak_when_reading FAILED                                                                                                                              [ 92%]
pyexiv2/tests/test_perf_on_ImageData.py::test_memory_leak_when_writing PASSED                                                                                                                              [ 96%]
pyexiv2/tests/test_perf_on_ImageData.py::test_stack_overflow PASSED                                                                                                                                        [100%]

==================================================================================================== FAILURES ====================================================================================================
_______________________________________________________________________________________________ test_read_raw_xmp ________________________________________________________________________________________________

    @check_md5
    def test_read_raw_xmp():
        with Image(path) as img:
>           assert len(img.read_raw_xmp()) == 4593
E           assert 4635 == 4593
E             +4635
E             -4593

pyexiv2/tests/test_func.py:28: AssertionError
_________________________________________________________________________________________________ test_read_all __________________________________________________________________________________________________

    @check_md5
    def test_read_all():
        with open(path, 'rb') as f:
            with ImageData(f.read()) as img:
                compare_dict(testdata.EXIF, img.read_exif())
                compare_dict(testdata.IPTC, img.read_iptc())
                compare_dict(testdata.XMP, img.read_xmp())
>               assert len(img.read_raw_xmp()) == 4593
E               assert 4635 == 4593
E                 +4635
E                 -4593

pyexiv2/tests/test_func_on_ImageData.py:12: AssertionError
_________________________________________________________________________________________ test_memory_leak_when_reading __________________________________________________________________________________________

    @check_md5
    def test_memory_leak_when_reading():
        p = psutil.Process(os.getpid())
        m0 = p.memory_info().rss
        for _ in range(1000):
            test_func.test_read_exif()
            test_func.test_read_iptc()
            test_func.test_read_xmp()
>           test_func.test_read_raw_xmp()

pyexiv2/tests/test_perf.py:16: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pyexiv2/tests/base.py:37: in wrapper
    ret = func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    @check_md5
    def test_read_raw_xmp():
        with Image(path) as img:
>           assert len(img.read_raw_xmp()) == 4593
E           assert 4635 == 4593
E             +4635
E             -4593

pyexiv2/tests/test_func.py:28: AssertionError
_________________________________________________________________________________________ test_memory_leak_when_reading __________________________________________________________________________________________

    @check_md5
    def test_memory_leak_when_reading():
        p = psutil.Process(os.getpid())
        m0 = p.memory_info().rss
        for _ in range(1000):
>           test_func_on_ImageData.test_read_all()

pyexiv2/tests/test_perf_on_ImageData.py:13: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pyexiv2/tests/base.py:37: in wrapper
    ret = func(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    @check_md5
    def test_read_all():
        with open(path, 'rb') as f:
            with ImageData(f.read()) as img:
                compare_dict(testdata.EXIF, img.read_exif())
                compare_dict(testdata.IPTC, img.read_iptc())
                compare_dict(testdata.XMP, img.read_xmp())
>               assert len(img.read_raw_xmp()) == 4593
E               assert 4635 == 4593
E                 +4635
E                 -4593

pyexiv2/tests/test_func_on_ImageData.py:12: AssertionError
============================================================================================ short test summary info =============================================================================================
FAILED pyexiv2/tests/test_func.py::test_read_raw_xmp - assert 4635 == 4593
FAILED pyexiv2/tests/test_func_on_ImageData.py::test_read_all - assert 4635 == 4593
FAILED pyexiv2/tests/test_perf.py::test_memory_leak_when_reading - assert 4635 == 4593
FAILED pyexiv2/tests/test_perf_on_ImageData.py::test_memory_leak_when_reading - assert 4635 == 4593
========================================================================================= 4 failed, 22 passed in 10.42s ==========================================================================================
d````

Writing arrays into exif segment is not working

Some Exif tags store a list of values, such as GPS latitude and longitude, which take a list of three rationals to store the angle in a "degrees minutes seconds" format.

For example, one would expect to be able to write something in the form

image.modify_exif({
    'Exif.GPSInfo.GPSLongitude': ['30/1', '50/1', '12345/1000'],
    'Exif.GPSInfo.GPSLatitude': ['30/1', '50/1', '12345/1000'],
})

and read back successfully the values.

Looking at the api C++ code, arrays seems to be supported in the XMP segments. I believe that porting the same behaviour to the exif part should be straightforward.

Thanks for the good work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.