Копирование и запись информации EXIF из одного изображения в другое с помощью pyexiv2
Я пытаюсь скопировать EXIF-информацию из файла изображения в измененную версию того же изображения, используя pyexiv2. В поисках решения я наткнулся на сообщение в Stack Overflow. Похоже, что API, используемые в функции, устарели и недоступны в последней версии. Основываясь на последнем документе, я создал такую функцию
def get_exif(file):
"""
Retrieves EXIF information from a image
"""
ret = {}
metadata = pyexiv2.ImageMetadata(str(file))
metadata.read()
info = metadata.exif_keys
for key in info:
data = metadata[key]
ret[key] = data.raw_value
return ret
def write_exif(originFile, destinationFile, **kwargs):
"""
This function would write an exif information of an image file to another image file
"""
exifInformation = get_exif(originFile)
metadata = pyexiv2.ImageMetadata(str(destinationFile))
for key, value in exifInformation.iteritems():
metadata[key] = value
copyrightName = kwargs.get('copyright', None)
if copyrightName != None:
metadata['Exif.Image.Copyright'] = copyrightName
try:
metadata.write()
except:
return False
else:
return True
Но это заканчивается ошибкой
Типы аргументов Python в _ExifTag._setParentImage(_ExifTag, NoneType) не соответствуют сигнатуре C++: _setParentImage(exiv2wrapper::ExifTag {lvalue}, exiv2wrapper::Image {lvalue})
Теперь я не знаю, что пошло не так. Может ли кто-нибудь помочь мне? Спасибо
РЕДАКТИРОВАТЬ
Исходя из предложения @unutbu, я изменил data.raw_value в методе get_exif() на data.value, но все еще сталкиваюсь с той же проблемой. Вставляю больше информации об этой ошибке:
Python argument types in
_ExifTag._setParentImage(_ExifTag, NoneType)
did not match C++ signature:
_setParentImage(exiv2wrapper::ExifTag {lvalue}, exiv2wrapper::Image {lvalue})
Request Method: POST
Request URL: http://localhost:8000/accounts/photography/
Django Version: 1.3.1
Exception Type: ArgumentError
Exception Value:
Python argument types in
_ExifTag._setParentImage(_ExifTag, NoneType)
did not match C++ signature:
_setParentImage(exiv2wrapper::ExifTag {lvalue}, exiv2wrapper::Image {lvalue})
Exception Location: /usr/lib64/python2.7/site-packages/pyexiv2/exif.py in _set_owner, line 107
**Traceback**
/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py in get_response
response = callback(request, *callback_args, **callback_kwargs) ...
/usr/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py in _wrapped_view
return view_func(request, *args, **kwargs) ...
/home/swaroop/public_html/xyz/xyz/apps/photography/views.py in accountsPhotoList
write_exif(originFile=filePath, destinationFile=output) ...
/home/swaroop/public_html/xyz/xyz/library/imageManipulation.py in write_exif
metadata[key] = value ...
/usr/lib64/python2.7/site-packages/pyexiv2/metadata.py in __setitem__
return getattr(self, '_set_%s_tag' % family)(key, tag_or_value) ...
/usr/lib64/python2.7/site-packages/pyexiv2/metadata.py in _set_exif_tag
tag._set_owner(self) ...
/usr/lib64/python2.7/site-packages/pyexiv2/exif.py in _set_owner
self._tag._setParentImage(metadata._image) ...
Python Executable: /usr/bin/python2.7
Python Version: 2.7.2
2 ответа
С pyexiv2 версии 0.3 решение @user2431382 не позволит записывать EXIF-теги в destination_file!= Source_file. Следующая версия работает для меня:
m1 = pyexiv2.ImageMetadata( source_filename )
m1.read()
# modify tags ...
# m1['Exif.Image.Key'] = pyexiv2.ExifTag('Exif.Image.Key', 'value')
m1.modified = True # not sure what this is good for
m2 = pyexiv2.metadata.ImageMetadata( destination_filename )
m2.read() # yes, we need to read the old stuff before we can overwrite it
m1.copy( m2 )
m2.write()
Вместо metadata['Exif.Image.Copyright'] = copyrightName
Вы должны использовать синтаксис как
metadata['Exif.Image.Copyright'] = pyexiv2.ExifTag('Exif.Image.Copyright', copyrightName)
Примечание: значение copyrightName должно быть строкой для "Exif.Image.Copyright"
Полный пример
import pyexiv2
metadata = pyexiv2.ImageMetadata(image_name)
metadata.read()
metadata.modified = True
metadata.writable = os.access(image_name ,os.W_OK)
metadata['Exif.Image.Copyright'] = pyexiv2.ExifTag('Exif.Image.Copyright', 'copyright@youtext')
metadata.write()
надеюсь, это поможет вам