Frage

Wie kann ich überprüfen, ob eine Datei von einem Benutzer hochgeladen eine echte jpg-Datei in Python (Google App Engine) ist?

Dies ist, wie weit ich jetzt habe:

Script empfängt Bild über HTML-Formular Post und wird durch den folgenden Code verarbeitet

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

Ich fand mimetypes.guess_type, aber es funktioniert für mich nicht.

War es hilfreich?

Lösung

Wenn Sie mehr benötigen als bei Erweiterung suchen, wäre eine Möglichkeit, die JPEG-Header zu lesen und prüfen, ob es gültige Daten übereinstimmt. Das Format hierfür ist:

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

so eine schnelle Erkenner wäre:

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

Dies wird jedoch keine schlechten Daten im Körper fängt. Wenn Sie eine robustere überprüfen möchten, können Sie versuchen, es das Laden mit PIL . zB:

from PIL import Image
def is_jpg(filename):
    try:
        i=Image.open(filename)
        return i.format =='JPEG'
    except IOError:
        return False

Andere Tipps

keine Notwendigkeit, die PIL lybrary dafür zu bedienen und zu installieren, gibt es das imghdr Standardmodul genau für diese Art der Nutzung fited.

Siehe http://docs.python.org/library/imghdr.html

import imghdr

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

Wie Sie ein Bild aus einem Stream Sie den Stream Option wahrscheinlich wie folgt verwenden können:

image_type = imghdr.what(filename, incomming_image)

Actualy funktioniert dies für mich in Pylons (auch wenn ich alles noch nicht fertig): in der Mako-Vorlage:

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

im Upload-Controler:

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

Eine allgemeine Lösung ist die Python-Bindung an den Unix-Befehl „file“ zu verwenden. das Paket python-magic Dazu installieren. Beispiel:

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()

Verwenden Sie PIL . Wenn es die Datei öffnen kann, es ist ein Bild.

Aus dem Tutorial ...

>>> import Image
>>> im = Image.open("lena.ppm")
>>> print im.format, im.size, im.mode

Das letzte Byte der JPEG-Dateispezifikation scheint darüber hinaus nur E0 zu variieren. die ersten drei Fang ‚gut genug‘ eine heuristischen Signatur zuverlässig zu erkennen, ob die Datei eine JPEG ist. Bitte siehe unten geänderten Vorschlag:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top