Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
バイナリ ⇔ 文字列 の相互変換をするだけなので楽
http://www.cipa.jp/std/documents/j/DC-008-2012_J.pdf
ページ49 / 195のUserComment参照
UserCommentフィールドの値を バイナリ⇔文字列型 の変換する関数の実装
piexif/_helper.pyに実装
引数、返り値などは下記のような具合に
def load(data):
"""
Convert "UserComment" value in exif format to str.
:param bytes data: "UserComment" value from exif
:return: u"foobar"
:rtype: str(Unicode)
"""
def dump(data, encoding="ascii"):
"""
Convert str to appropriate format for "UserComment".
:param data: Like u"foobar"
:param str encoding: "ascii", "jis", or "unicode"
:return: b"ASCII\x00\x00\x00foobar"
:rtype: bytes
"""
テスト -> "python setup.py test" -> VisualStudioがあれば、ソリューションを読み込むだけでテストエクスプローラから簡単にできる
tests/s_test.py
test_load_user_comment
test_dump_user_comment
Owner

hMatoba commented Sep 6, 2017

”フィールドの値はASCII、JIS、UNICODE、UNDEFINEDのどれかでエンコードされている”

・UNICODEでエンコードされているってどういうこと?UCS2?UTF16?

・UNDEFINEDってのは定義されていないってこと。
 だったら適当にデコードしちゃうとおかしくなるから、この場合はバイト列で値を返す?
 でもそうすると、一つの関数からの戻り値がstrとbytesで混在する

Owner

hMatoba commented Sep 8, 2017

exiftoolを使ってみた。

exiftool -UserComment="ユーザーコメント" uc_j.jpg

UserCommentに日本語で"あいう"と入れてみたところ、b'UNICODE\x000B0D0F'という値で書き込まれていた。
つまりエンコーディング情報を入れているヘッダが先頭に長さ8であって、それに続く文字列のエンコーディングは、ユニコードが指定されている場合はUTF16のビッグエンディアンで行われていた。

UNICODEが指定されたケースは .encode("utf_16_be") でいく。
あとはUNDEFINEDをどうするか。

Owner

hMatoba commented Sep 8, 2017

UNDEFINEDに関しては、UNDEFINEDとされている時点でエンコードもデコードもできない。
・入力をそのまま返す→ASCIIやJISの場合と返す値が一致しなくなるので嫌
・latinでエンコード、デコード→違ってない?違ってる
・Noneを返す→名案がないときの落としどころ
・Exceptionを上げる→ValueErrorあたりで「UNDEFINEDだからどうにもできないよ」的なメッセージを出す

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment