Pregunta

¿Cómo puedo verificar si un archivo cargado por un usuario es un archivo jpg real en Python (Google App Engine)?

Esto es lo lejos que llegué ahora:

El script recibe la imagen a través de la publicación de formulario HTML y se procesa con el siguiente código

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

Encontré mimetypes.guess_type, pero no me funciona.

¿Fue útil?

Solución

Si necesita algo más que mirar la extensión, una forma sería leer el encabezado JPEG y verificar que coincida con los datos válidos. El formato para esto es:

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

entonces un reconocimiento rápido sería:

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

Sin embargo, esto no capturará ningún dato incorrecto en el cuerpo. Si desea una verificación más sólida, puede intentar cargarla con PIL . por ejemplo:

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

Otros consejos

No es necesario usar e instalar la biblioteca PIL para esto, existe el módulo estándar imghdr que se ajusta exactamente a este tipo de uso.

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

import imghdr

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

Como tiene una imagen de una transmisión, puede usar la opción de transmisión probablemente así:

image_type = imghdr.what(filename, incomming_image)

En realidad, esto funciona para mí en Pylons (incluso si no he terminado todo): en la plantilla de 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()}

en el controlador de carga:

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

Una solución más general es utilizar el enlace de Python al archivo Unix " mando. Para esto, instale el paquete python-magic. Ejemplo:

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

Utilice PIL . Si puede abrir el archivo, es una imagen.

Del tutorial ...

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

El último byte de la especificación del archivo JPEG parece variar más allá de solo e0. Capturar los primeros tres es "suficientemente bueno" de una firma heurística para identificar de manera confiable si el archivo es un jpeg. Consulte la propuesta modificada a continuación:

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top