2008-11-05 14 views
15

मैं कैसे जांच सकता हूं कि उपयोगकर्ता द्वारा अपलोड की गई फ़ाइल पाइथन (Google App Engine) में वास्तविक jpg फ़ाइल है या नहीं?पायथन: जांचें कि अपलोड की गई फ़ाइल jpg

यह कितनी दूर मैं अब तक मिल गया है:

स्क्रिप्ट HTML फ़ॉर्म पोस्ट के माध्यम से छवि प्राप्त करता है और निम्नलिखित कोड

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

मैं mimetypes.guess_type पाया द्वारा संसाधित किया जाता है, लेकिन यह के लिए काम नहीं करता है मुझे।

उत्तर

36

यदि आपको एक्सटेंशन देखने से अधिक की आवश्यकता है, तो एक तरीका जेपीईजी हेडर को पढ़ना होगा, और जांचें कि यह वैध डेटा से मेल खाता है। इस के लिए प्रारूप है:

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

तो एक त्वरित recogniser होगा:

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 
0

PIL का उपयोग करें। अगर यह फ़ाइल खोल सकता है, तो यह एक छवि है।

ट्यूटोरियल से ...

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

यह ऐप इंजन में काम नहीं करेगा: पीआईएल में सी कोड है और इसलिए उपलब्ध नहीं है। छवियों एपीआई (http://code.google.com/appengine/docs/images/) पीआईएल का उपयोग करता है, लेकिन यह stubbed बाहर है। – chryss

33

का उपयोग करें और इस बात के लिए जनहित याचिका lybrary स्थापित करने के लिए कोई ज़रूरत नहीं है, वहाँ imghdr मानक मॉड्यूल वास्तव में उपयोग के इस तरह के लिए fited है।

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()} 
अपलोड 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 
+3

+1 मानक मानक मॉड्यूल –

+1

के लिए .jpg फ़ाइलों के लिए 'imghdr.what() 'रिटर्न' कोई नहीं '। – Rico

1

एक अधिक सामान्य समाधान अजगर यूनिक्स "फ़ाइल" कमांड के लिए बाध्य उपयोग करने के लिए है। इसके लिए, पैकेज पायथन-जादू स्थापित करें। उदाहरण:

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

जेपीईजी फ़ाइल विनिर्देश का अंतिम बाइट सिर्फ e0 से भिन्न होता है। पहले तीन को कैप्चर करना एक ह्यूरिस्टिक हस्ताक्षर का 'पर्याप्त पर्याप्त' है जो विश्वसनीय रूप से यह पहचानने के लिए है कि फ़ाइल एक जेपीईजी है या नहीं। कृपया नीचे संशोधित प्रस्ताव देखें:

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 
संबंधित मुद्दे