アップロードされた画像を取得してAmazonS3に保存し、URLをSQLiteデータベースに保存するWebアプリを構築しています。残念ながら、EXIFタグを使用すると、スマートフォンで撮影された画像が回転して表示されます(EXIF方向タグ付きの風景画像であるため)。
現在、私の環境ではPOSTデータからファイルを取得し、静的ファイルフォルダーに保存し、PILを使用してイメージを回転させ(必要な場合)、S3にプッシュし、最後にローカルコピーを削除します。関連するコードの一部を次に示します。
from PIL import Image
import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key
def fix_orientation(filename):
img = Image.open(filename)
if hasattr(img, '_getexif'):
exifdata = img._getexif()
try:
orientation = exifdata.get(274)
except:
# There was no EXIF Orientation Data
orientation = 1
else:
orientation = 1
if orientation is 1: # Horizontal (normal)
pass
elif orientation is 2: # Mirrored horizontal
img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 3: # Rotated 180
img = img.rotate(180)
elif orientation is 4: # Mirrored vertical
img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 5: # Mirrored horizontal then rotated 90 CCW
img = img.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 6: # Rotated 90 CCW
img = img.rotate(-90)
elif orientation is 7: # Mirrored horizontal then rotated 90 CW
img = img.rotate(90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 8: # Rotated 90 CW
img = img.rotate(90)
#save the result and overwrite the originally uploaded image
img.save(filename)
def push_to_s3(**kwargs):
try:
conn = S3Connection(app.config["S3_KEY"], app.config["S3_SECRET"])
buckets = [bucket.name for bucket in conn.get_all_buckets()]
bucket = conn.get_bucket(app.config["S3_BUCKET"])
k = Key(bucket)
k.key = app.config["S3_UPLOAD_DIR"] + kwargs.get("filename")
k.set_contents_from_filename(kwargs.get("photo"))
k.make_public()
return k
except Exception, e:
abort(500)
これがPOSTデータの処理です
# Retrieving Form POST Data
fi = request.files.get("file")
#print "Storing and Rotating File (if needed)"
f = photos.save(fi)
path = photos.path(f)
fix_orientation(path)
#print "Uploading to S3"
img = push_to_s3(photo=path, filename=filename)
#print "Deleting Local Version"
os.remove(path)
上記のソリューションはHerokuのサーバーで機能しますが、ソリューションが非常にダクトテープで固定されているように見えます。私がしていることを行うためのよりクリーンな方法はありますか?つまり、アップロードされたファイルを取得し、メモリからローテーションしてからS3にプッシュしますか?
また、アップロード画像の保存を処理するためにFlask-Uploadsを使用しています。
含む-それは価値がある何のために、枕は、ファイル名以外の入力の数をサポートしbytearray
、buffer
、とfile-like object
。からロードされるものrequest.files
はすべてFileStorage
ファイルのようなオブジェクトであるため、3番目はおそらくあなたが探しているものです。これにより、ロードと変換のコードが次のように簡略化されます。
def fix_orientation(file_like_object):
img = Image.open(filename)
# ... snip ...
data = BytesIO()
img.save(data)
return data
ファイルシステムをあまり使用せずにデータを渡すため、次の代わりにboto.s3.key.Key
のset_contents_from_file
メソッドを使用するように切り替えることもできますset_contents_from_filename
。
def push_to_s3(photo, filename):
# ... snip ...
k.set_contents_from_file(photo, rewind=True)
# ... etc. ...
これにより、結果の実装が次のように簡素化されます。
# Retrieving Form POST Data
fi = request.files.get("file")
# print "Rotating File (if needed)"
fi = fix_orientation(fi)
# print "Uploading to S3"
push_to_s3(photo=fi, filename=filename)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加