15

ユーザーがアップロードしたファイルが Python (Google App Engine) で実際の jpg ファイルかどうかを確認するにはどうすればよいですか?

これは私が今までに得た距離です:

スクリプトは HTML フォーム ポスト経由で画像を受け取り、次のコードで処理されます

...
incomming_image = self.request.get("img")
image = db.Blob(incomming_image)
...

mimetypes.guess_type を見つけましたが、うまくいきません。

4

5 に答える 5

36

拡張機能だけでなく、JPEGヘッダーを読み取り、有効なデータと一致することを確認する方法もあります。この形式は次のとおりです。

Start Marker  | JFIF Marker | Header Length | Identifier
0xff, 0xd8    | 0xff, 0xe0  |    2-bytes    | "JFIF\0"

したがって、迅速な認識は次のようになります。

def is_jpg(filename):
    data = open(filename,'rb').read(11)
    if data[:4] != '\xff\xd8\xff\xe0': return False
    if data[6:] != 'JFIF\0': return False
    return True

ただし、これは体内の悪いデータをキャッチしません。より堅牢なチェックが必要な場合は、PILを使用してロードしてみてください。例えば:

from PIL import Image
def is_jpg(filename):
    try:
        i=Image.open(filename)
        return i.format =='JPEG'
    except IOError:
        return False
于 2008-11-05T21:17:54.463 に答える
34

このためにPILlybraryを使用してインストールする必要はありません。この種の使用法にぴったり合う、imghdr標準モジュールがあります。

http://docs.python.org/library/imghdr.htmlを参照してください

import imghdr

image_type = imghdr.what(filename)
if not image_type:
    print "error"
else:
    print image_type

ストリームからの画像があるので、おそらく次のようなストリームオプションを使用できます。

image_type = imghdr.what(filename, incomming_image)

実際、これはPylonsで機能します(すべてを完了していなくても):Makoテンプレートで:

${h.form(h.url_for(action="save_image"), multipart=True)}
Upload file: ${h.file("upload_file")} <br />
${h.submit("Submit", "Submit")}
${h.end_form()}

アップロードコントローラー内:

def save_image(self):
    upload_file = request.POST["upload_file"]
    image_type = imghdr.what(upload_file.filename, upload_file.value)
    if not image_type:
        return "error"
    else:
        return image_type
于 2009-06-24T18:18:02.787 に答える
1

より一般的な解決策は、Python バインディングを Unix の "file" コマンドに使用することです。このために、パッケージ python-magic をインストールします。例:

import magic

ms = magic.open(magic.MAGIC_NONE)
ms.load()
type =  ms.file("/path/to/some/file")
print type

f = file("/path/to/some/file", "r")
buffer = f.read(4096)
f.close()

type = ms.buffer(buffer)
print type

ms.close()
于 2011-04-19T13:34:07.593 に答える
0

PILを使用します。ファイルを開くことができれば、それは画像です。

チュートリアルから...

>>> import Image
>>> im = Image.open("lena.ppm")
>>> print im.format, im.size, im.mode
于 2008-11-05T21:29:10.637 に答える
0

JPEG ファイル仕様の最後のバイトは、e0 だけではないようです。最初の 3 つをキャプチャすることは、ファイルが jpeg であるかどうかを確実に識別するためのヒューリスティック署名の「十分な」ものです。以下の変更された提案を参照してください。

def is_jpg(filename):
    data = open("uploads/" + filename,'rb').read(11)
    if (data[:3] == "\xff\xd8\xff"):
        return True
    elif (data[6:] == 'JFIF\0'): 
        return True
    else:
        return False
于 2015-03-06T20:39:54.610 に答える