2015-04-22 3 views
0

Я пишу сценарий для сохранения метаданных в 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.

Что мне делать? Любые предложения будут полезны.

спасибо.

+0

Если это поможет: >>> pyexiv2 .__ version__ '0.3.2' >>> PIL.VERSION '1.1.7' >>> PIL.PILLOW_VERSION '2.7.0' – Derwent

ответ

0

Проблема с линиями

if index in imgmeta.iptc_keys:  
    imgmeta[index] = [value] 
if index in imgmeta.exif_keys: 
    imgmeta[index] = value 

Они должны быть

if index[:4] == 'Iptc' :   
    imgmeta[index] = [value] 
if index[:4] == 'Exif' : 
    imgmeta[index] = value 

Поскольку ключ не будет найден в списке ключей в imgmeta, так как никто не написал бы, чтобы те, ключей до. Еще один случай, когда я трачу часы на поиски проблемы в неправильном месте.

Смежные вопросы