Python: проверьте, является ли загруженный файл jpg
Как проверить, является ли файл, загруженный пользователем, реальным файлом jpg в Python (Google App Engine)?
Вот как я дошел до сих пор:
Script получает изображение через сообщение формы HTML и обрабатывается следующим кодом
...
incomming_image = self.request.get("img")
image = db.Blob(incomming_image)
...
Я нашел mimetypes.guess_type, но это не работает для меня.
Ответы
Ответ 1
Если вам нужно больше, чем смотреть на расширение, одним из способов было бы прочитать заголовок 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
Ответ 2
Не нужно использовать и устанавливать 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 (даже если я еще не закончил все):
в шаблоне Мако:
${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
Ответ 3
Более общее решение - использовать привязку Python к команде "файл" Unix. Для этого установите пакет 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()
Ответ 4
Используйте PIL. Если он может открыть файл, это изображение.
Из учебника...
>>> import Image
>>> im = Image.open("lena.ppm")
>>> print im.format, im.size, im.mode
Ответ 5
Последний байт спецификации файла 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