Python:アップロードされたファイルがjpgかどうかを確認します
-
06-07-2019 - |
質問
ユーザーがアップロードしたファイルがPython(Google App Engine)の実際のjpgファイルであるかどうかを確認するにはどうすればよいですか?
これは、私が今までにどれだけ手に入れたかです:
スクリプトはHTMLフォームポスト経由で画像を受け取り、次のコードで処理されます
...
incomming_image = self.request.get("img")
image = db.Blob(incomming_image)
...
mimetypes.guess_typeを見つけましたが、うまくいきません。
解決
拡張機能を見る以上のものが必要な場合、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
他のヒント
このためにPIL lybraryを使用およびインストールする必要はありません。この種の使用にぴったりの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
より一般的な解決策は、Unixの「ファイル」にPythonバインディングを使用することです。コマンド。そのためには、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()
PIL を使用します。ファイルを開くことができる場合、それは画像です。
チュートリアルから...
>>> import Image
>>> im = Image.open("lena.ppm")
>>> print im.format, im.size, im.mode
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