Python: проверьте, загружен ли файл в формате jpg - PullRequest
15 голосов
/ 06 ноября 2008

Как проверить, является ли загруженный пользователем файл настоящим jpg-файлом в Python (Google App Engine)?

Вот как далеко я дошла:

Скрипт получает изображение через HTML Form Post и обрабатывается следующим кодом

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

Я нашел mimetypes.guess_type, но он не работает для меня.

Ответы [ 5 ]

36 голосов
/ 06 ноября 2008

Если вам нужно больше, чем просто смотреть на расширение, одним из способов будет прочитать заголовок 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
34 голосов
/ 24 июня 2009

Для этого не нужно использовать и устанавливать библиотеку PIL, есть стандартный модуль 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)

На самом деле это работает для меня в Пилонах (даже если я еще не все закончил): в шаблоне Мако:

${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
1 голос
/ 19 апреля 2011

Более общим решением является использование привязки 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()
0 голосов
/ 06 марта 2015

Последний байт спецификации файла JPEG, по-видимому, выходит за пределы просто e0. Захват первых трех является «достаточно» эвристической сигнатурой, чтобы надежно определить, является ли файл 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
0 голосов
/ 06 ноября 2008

Используйте PIL . Если он может открыть файл, это изображение.

Из учебника ...

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