主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python: Exifをもったまま画像をリサイズする Resize a Image by Python Keeping Exif

                
tags: python
**************************
'14/9/14追記
https://pypi.python.org/pypi/Piexif
**************************

 Python + GAEで画像のアップローダを作った。画像のリサイズをPILでしたことによってExifが失われた。Exifには撮影時のカメラの設定なども記録されているので、うまく撮れた写真の設定を確認するなどで有用だ。Exifが消えるのは都合が悪いことだったので、Exifをキープしたまま画像リサイズができる関数を書いた。特徴は純粋なPythonスクリプトなので、Pythonが動くならどこでも使える点。

 すでにPythonでもExifパーサなどはいくつかあって、Exif情報を参照するのは困らない。だがExifを移植できるものはなかなか見つからなかった(http://www.blog.pythonlibrary.org/2010/03/28/getting-photo-metadata-exif-using-python/)。あったとしてもC++で書かれたもののPythonラッパーだったので、GAEサーバでは使えなかった。

テスト環境は下記のとおりだが、基本的な関数しか使っていないので少しぐらい古いバージョンでも動くだろう。
Python 2.7
PIL 1.1.7

I wrote a python code to resize a image keeping Exif. PIL size manipulation(Image.resize(), Image.thumbnail()) generates new image. The image loses original image's Exif. There are some Exif parsers that can use on Python. The function I wanted was Exif transplanter, Whereas I couldn't find it. So I wrote this code.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
##########################################################
# filename: input filename
# output: output filename
# size: list of new image size(ex. [100, 100])
# bin_return: If it is True, this function doesn't save image, but return image file data

from PIL import Image
import cStringIO

def get_thumbnail(filename, output, size=[200, 200], bin_return = False):
if (type(size) != list) or (len(size) != 2):
raise

with open(filename, 'rb') as f:
data = f.read()
start = data.find("\xff\xe1")
if start < 0:
if not bin_return:
im = Image.open(filename)
im.thumbnail(size, Image.ANTIALIAS)
im.save(output, "JPEG")
return False
else:
new_data = cStringIO.StringIO()
im = Image.open(filename)
im.thumbnail(size, Image.ANTIALIAS)
im.save(new_data, "JPEG")
return new_data
segments = slice2segments(data)
exif = get_exif(segments)

thumb = cStringIO.StringIO()
im = Image.open(filename)
im.thumbnail(size, Image.ANTIALIAS)
im.save(thumb, "JPEG")

data2 = thumb.getvalue()
start2 = data2.find("\xff\xdb")
new_data = data2[0:start2] + exif + data2[start2:]

if not bin_return:
with open(output, "w+b") as f:
f.write(new_data)
return False
else:
return new_data

def slice2segments(data):
head = 0
segments = [];

while 1:
if (data[head: head + 2] == "\xff\xd8"):
head += 2
else:
length = int(data[head + 2].encode('hex'), 16) * 256 + int(data[head + 3].encode('hex'), 16)
endPoint = head + length + 2
seg = data[head: endPoint]
segments.append(seg);
head = endPoint
if (head > len(data)): break
if (data[head: head + 2] == "\xff\xda"): break
return segments

def get_exif(segments):
for seg in segments:
if seg[0:2] == "\xff\xe1":
return seg
return False

if __name__ == "__main__":
get_thumbnail(r'C:\Users\hoge\Desktop\4249.jpg', r'C:\Users\hoge\Desktop\hoge.jpg')
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。