2008-11-05 31 views
15

Làm cách nào để kiểm tra xem tệp được tải lên bởi người dùng có phải là tệp jpg thực trong Python (Google App Engine) không?Python: Kiểm tra xem tệp đã tải lên có phải là jpg

Đây là cách nay tôi có bây giờ:

Script nhận hình ảnh qua HTML Form Bưu chính, được xử lý bởi các mã sau

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

tôi thấy mimetypes.guess_type, nhưng nó không làm việc cho tôi.

Trả lời

36

Nếu bạn cần nhiều hơn là xem phần mở rộng, một cách là đọc tiêu đề JPEG và kiểm tra xem nó có khớp với dữ liệu hợp lệ hay không. Định dạng cho điều này là:

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

do đó, một recogniser nhanh chóng sẽ là:

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 

Tuy nhiên điều này sẽ không bắt bất kỳ dữ liệu xấu trong cơ thể. Nếu bạn muốn kiểm tra mạnh mẽ hơn, bạn có thể thử tải bằng PIL. ví dụ:

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

Sử dụng PIL. Nếu nó có thể mở tập tin, nó là một hình ảnh.

Từ hướng dẫn ...

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

Điều này sẽ không hoạt động trong App Engine: PIL chứa mã C và do đó không khả dụng. API hình ảnh (http://code.google.com/appengine/docs/images/) sử dụng PIL, nhưng nó bị loại bỏ. – chryss

33

Không cần phải sử dụng và cài đặt lybrary PIL cho điều này, đó là imghdr tiêu chuẩn mô-đun chính xác fited cho loại sử dụng.

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

import imghdr 

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

Như bạn có một hình ảnh từ một dòng bạn có thể sử dụng tùy chọn dòng có lẽ là như thế này:

image_type = imghdr.what(filename, incomming_image) 

Actualy này làm việc cho tôi trong giá treo (thậm chí nếu tôi chưa hoàn thành mọi thứ): trong mẫu 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()} 

trong ứng dụng điều khiển tải lên:

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

+1 cho imghdr là một mô-đun chuẩn –

+1

Đối với các tệp .jpg 'imghdr.what()' trả về 'Không có'. – Rico

1

Một giải pháp tổng quát hơn là sử dụng Python ràng buộc với Unix "tập tin" lệnh. Đối với điều này, cài đặt gói python-magic. Ví dụ:

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

byte cuối cùng của đặc tả tệp JPEG dường như khác với chỉ e0. Chụp ba chữ cái đầu tiên là 'đủ tốt' của chữ ký heuristic để xác định một cách đáng tin cậy xem tệp có phải là tệp jpeg hay không. Vui lòng xem bên dưới đề xuất sửa đổi:

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 
Các vấn đề liên quan