0

メタデータを jpg 画像に保存し、Wordpress 用にサイズ変更するスクリプトを作成しています。PIL.Image.thumbnail()でjpg(pngではなく)のサイズを変更した直後に画像で使用しようとするまで、jpegとpngを使用してうまくいきます

質問への回答を手伝ってくれる人を助けるために、すべてを 1 つの読みやすいクラスに圧縮しようとしました。主なクラスは 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 が画像のサイズを変更した後はまったく機能しません。これは、PIL を使用してメタデータを保存する .PNG では発生しないため、pyexiv2 が問題であることが示唆されます。

何を試すべきですか?どんな提案も役に立ちます。

ありがとうございました。

4

1 に答える 1

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 のキーのリストに見つからないため、以前は誰もそれらのキーに書き込んでいないためです。間違った場所で問題を探すのに何時間も費やした別のケース。

于 2015-04-23T04:04:29.107 に答える