S3にプッシュする前にフラスコ経由でアップロードされたスマートフォンの画像を回転させるよりクリーンな方法はありますか?

ツムニア

アップロードされた画像を取得して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を使用しています。

ショーン・ビエイラ

含む-それは価値がある何のために、枕は、ファイル名以外の入力の数をサポートしbytearraybuffer、と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.Keyset_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]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ