質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

Python piexifを使って画像のタグ情報を編集したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 121

per_

score 31

前提・実現したいこと

PythonプログラムからJPGの"タグ"を取得および編集したいと考えています。

Windows10
Pythonバージョン3.7
イメージ説明

できていること・わかっていること

調べているうち、Pillow(PIL)ライブラリではEXIF情報の取得しかできないと知りました。
そこで、取得および編集も可能であるpiexifライブラリも使用することを考えています。

上記2つのライブラリを用いて以下のことはできました。
・手動で設定してあるタグを取得する
・EXIFにおける、プロパティのタグ部分の情報
id:40094
tag名:XPKeyword

該当のソースコード

import pprint
from PIL import Image
import piexif

filename =  r"画像の絶対パス/nekohoge.jpg"
im = Image.open(filename)
exif = im._getexif()

for tag_id, value in exif.items():
    if tag_id == 40094:
        strv = str(value)
        print(strv.replace('\\x00', ''))
        #  >>>b'cat;test;cute'


exif_dict = piexif.load(im.info["exif"])

pprint.pprint(exif_dict)
# >>> {'0th': {270: b'neko_hoge',
#              34665: 2144,
#              40091: (110,0,101,0,107,0,111,0,95,0,104,0,111,0,103,0,101,0,0,0),
#              40094: (99,0,97,0,116,0,59,0,116,0,101,0,115,0,116,0,59,0,99,0,117,0,116,0,101,0,0,0)},
#     '1st': {},
#     'Exif': {},
#     'GPS': {},
#     'Interop': {},
#     'thumbnail': None}


※一部見やすいように表記を整えています。

わからないこと

  1. piexifを用いて取得したこの情報がタグにあたる部分だと思うのですが、
    40094: (99,0,97,0,116,0,59,0,116,0,101,0,115,0,116,0,59,0,99,0,117,0,116,0,101,0,0,0)
    PILを用いて得た情報と表示形式が大きく異なるため、どういう表示をしているのかがわかりません。
    ⇒自己解決しました。
    各要素の数字において、0は処理を飛ばし、他の数値をchr(数値)で表示することでcat;test;cuteを取得できました。
     
  2. 公式ドキュメントでは決まったid部分を変更することは可能なようですが、
    上記のような画像タグ(id:40094)部分を、指定して変更するやり方が分かりませんでした。
    そもそも不可能なのでしょうか?
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

エンコーディングutf-16-leで表現されたタプルのようなのでencode/decode関数を書きました。
これを介すると文字列として取得、変更できて保存もできました。

from PIL import Image
import piexif

def decode(t):
    b = bytes(t)
    return b[:-2].decode('utf-16-le')

def encode(s):
    b = s.encode('utf-16-le') + b'\x00\x00'
    return tuple([int(i) for i in b])


filename =  r"test.jpg"
im = Image.open(filename)
exif_dict = piexif.load(im.info["exif"])

keyword = exif_dict["0th"][piexif.ImageIFD.XPKeywords]  # 40094: {'name': 'XPKeywords', 'type': TYPES.Byte},
print(keyword) # (99, 0, 97, 0, 116, 0, 59, 0, 116, 0, 101, 0, 115, 0, 116, 0, 59, 0, 99, 0, 117, 0, 116, 0, 101, 0, 0, 0)

keyword = decode(keyword)
print(keyword) # cat;test;cute

keyword += ';dog'

keyword = encode(keyword)
print(keyword) # (99, 0, 97, 0, 116, 0, 59, 0, 116, 0, 101, 0, 115, 0, 116, 0, 59, 0, 99, 0, 117, 0, 116, 0, 101, 0, 59, 0, 100, 0, 111, 0, 103, 0, 0, 0)

exif_dict["0th"][piexif.ImageIFD.XPKeywords]= keyword

# 別ファイルに保存
exif_bytes = piexif.dump(exif_dict)
im.save('ret.jpg', "jpeg", exif=exif_bytes)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/20 11:56

    実現したいことを簡潔に行うことができました。
    エンコーデイングについて理解できていなかったので、これを機に勉強します。
    ご回答ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る