Я пишу сценарий для сохранения метаданных в jpg-изображениях и изменения их размера для Wordpress. Это было хорошо, работая с jpegs и png, пока я не попытаюсь использовать его на изображении непосредственно после изменения размера jpg (но не png) с PIL.Image.thumbnail()Блокировка файлов Pyexiv2 и PIL
Я попытался сжать все это в один класс для чтения, чтобы помочь каждому, кто может помочь ответить на вопрос. Основной класс - MetaGator (meta mitigator), который записывает заголовки атрибутов и «описание» в соответствующее поле метаданных в файле.
import PIL
from PIL import Image
from PIL import PngImagePlugin
from pyexiv2.metadata import ImageMetadata
from PIL import Image
import os
import re
from time import time, sleep
class MetaGator(object):
"""docstring for MetaGator"""
def __init__(self, path):
super(MetaGator, self).__init__()
if not os.path.isfile(path):
raise Exception("file not found")
self.dir, self.fname = os.path.split(path)
def write_meta(self, title, description):
name, ext = os.path.splitext(self.fname)
title, description = map(str, (title, description))
if(ext.lower() in ['.png']):
try:
new = Image.open(os.path.join(self.dir, self.fname))
except Exception as e:
raise Exception('unable to open image: '+str(e))
meta = PngImagePlugin.PngInfo()
meta.add_text("title", title)
meta.add_text("description", description)
try:
new.save(os.path.join(self.dir, self.fname), pnginfo=meta)
except Exception as e:
raise Exception('unable to write image: '+str(e))
elif(ext.lower() in ['.jpeg', '.jpg']):
try:
imgmeta = ImageMetadata(os.path.join(self.dir, self.fname))
imgmeta.read()
except IOError:
raise Exception("file not found")
for index, value in (
('Exif.Image.DocumentName', title),
('Exif.Image.ImageDescription', description),
('Iptc.Application2.Headline', title),
('Iptc.Application2.Caption', description),
):
print " -> imgmeta[%s] : %s" % (index, value)
if index in imgmeta.iptc_keys:
imgmeta[index] = [value]
if index in imgmeta.exif_keys:
imgmeta[index] = value
imgmeta.write()
else:
raise Exception("not an image file")
def read_meta(self):
name, ext = os.path.splitext(self.fname)
title, description = '', ''
if(ext.lower() in ['.png']):
oldimg = Image.open(os.path.join(self.dir, self.fname))
title = oldimg.info.get('title','')
description = oldimg.info.get('description','')
elif(ext.lower() in ['.jpeg', '.jpg']):
try:
imgmeta = ImageMetadata(os.path.join(self.dir, self.fname))
imgmeta.read()
except IOError:
raise Exception("file not found")
for index, field in (
('Iptc.Application2.Headline', 'title'),
('Iptc.Application2.Caption', 'description')
):
if(index in imgmeta.iptc_keys):
value = imgmeta[index].value
if isinstance(value, list):
value = value[0]
if field == 'title': title = value
if field == 'description': description = value
else:
raise Exception("not an image file")
return {'title':title, 'description':description}
if __name__ == '__main__':
print "JPG test"
fname_src = '<redacted>.jpg'
fname_dst = '<redacted>-test.jpg'
metagator_src = MetaGator(fname_src)
metagator_src.write_meta('TITLE', time())
print metagator_src.read_meta()
image = Image.open(fname_src)
image.thumbnail((10,10))
image.save(fname_dst)
metagator_dst = MetaGator(fname_dst)
metagator_dst.write_meta('TITLE', time())
print metagator_dst.read_meta()
sleep(5)
metagator_dst = MetaGator(fname_dst)
metagator_dst.write_meta('TITLE', time())
print metagator_dst.read_meta()
print "PNG test"
fname_src = '<redacted>.png'
fname_dst = '<redacted>-test.png'
metagator_src = MetaGator(fname_src)
metagator_src.write_meta('TITLE', time())
print metagator_src.read_meta()
image = Image.open(fname_src)
image.thumbnail((10,10))
image.save(fname_dst)
metagator_dst = MetaGator(fname_dst)
metagator_dst.write_meta('TITLE', time())
print metagator_dst.read_meta()
sleep(5)
metagator_dst = MetaGator(fname_dst)
metagator_dst.write_meta('TITLE', time())
print metagator_dst.read_meta()
Код я использовал, чтобы проверить это в основной и дает следующий результат:
JPG test
-> imgmeta[Exif.Image.DocumentName] : TITLE
-> imgmeta[Exif.Image.ImageDescription] : 1429683541.3
-> imgmeta[Iptc.Application2.Headline] : TITLE
-> imgmeta[Iptc.Application2.Caption] : 1429683541.3
{'description': '1429683541.3', 'title': 'TITLE'}
-> imgmeta[Exif.Image.DocumentName] : TITLE
-> imgmeta[Exif.Image.ImageDescription] : 1429683541.31
-> imgmeta[Iptc.Application2.Headline] : TITLE
-> imgmeta[Iptc.Application2.Caption] : 1429683541.31
{'description': '', 'title': ''}
-> imgmeta[Exif.Image.DocumentName] : TITLE
-> imgmeta[Exif.Image.ImageDescription] : 1429683546.32
-> imgmeta[Iptc.Application2.Headline] : TITLE
-> imgmeta[Iptc.Application2.Caption] : 1429683546.32
{'description': '', 'title': ''}
PNG test
{'description': '1429683546.32', 'title': 'TITLE'}
{'description': '1429683546.83', 'title': 'TITLE'}
{'description': '1429683551.83', 'title': 'TITLE'}
Как вы можете видеть, в тесте JPG, он отлично работает на обычном файле, но не работает вообще после того, как PIL изменяет размер изображения. Этого не происходит с .PNG, который использует PIL для сохранения метаданных, что заставило бы меня предположить, что это проблема pyexiv2.
Что мне делать? Любые предложения будут полезны.
спасибо.
Если это поможет: >>> pyexiv2 .__ version__ '0.3.2' >>> PIL.VERSION '1.1.7' >>> PIL.PILLOW_VERSION '2.7.0' – Derwent