目録
Exifの削除
2023-04-01
pythonによるexifの削除について。解説はコードの後に。
def simple_delete_exif (file_name, new_file_name):
with open (file_name, 'rb' ) as f:
data = f.read()
start_of_image = data.index(b' \xff\xd8 ' )
start_of_scan = data.index(b' \xff\xda ' )
application_segment_marker = []
for header in range (start_of_image, start_of_scan, 2 ):
tag = data[header:header + 2 ]
if b' \xff\xe0 ' <= tag <= b' \xff\xef ' :
tag_length = struct.unpack('>H' , data[header + 2 :header + 4 ])[0 ]
application_segment_marker.append(data[header:header + tag_length + 2 ])
with open (new_file_name, 'wb' ) as g:
new_data = data
for marker in application_segment_marker:
new_data = new_data.replace(marker, b'' )
g.write(new_data)
画像データを開く
画像データを読み込むにはopen
を使い、開くモードとして読み取り専用の'r'
、書き込み専用の'w'
、追記専用の'a'
がある。また'b'
はバイナリデータの読み込みモードを表している。テキスト形式なら't'
を選ぶ。
exifの削除
ExifはJPEGデータの始まりSOI (start of image) と画像データの始まりSOS (start of scan) の間に存在する。そのためSOIを表すマーカ「b'\xff\xd8'
」とSOSを表すマーカ「b'\xff\xda'
」の位置をindex
メソッドによって取得している。シングルクォーテーションの前にある「b」はバイナリデータで表すための表記。
Exifが埋め込まれるのはAPP (application segment marker) がb'\xff\xe0'
からb'\xff\xef'
。2バイト区切りで進めて埋め込まれていたらAPPマーカの次の2バイトでデータの長さが記されているのでその分を足して一つのExifデータとして保存している。
struct.unpack
はバイナリデータを数字に変換する。第一引数はエンディアンと呼ばれるものでCPUに依存して、バイナリデータの読む向きが変化する。「\x00 \x01」を数字にしたとき1と読み込むのはビッグエンディアン、逆さまにして「\x01 \x00」として257と読むのがリトルエンディアン。
最後に書き込みをする前にExifのデータ列を空白に置き換えることで削除している。