यदि कोई फ़ाइल एक वैध छवि फ़ाइल है, तो कैसे जांचें?


105

मैं वर्तमान में पीआईएल का उपयोग कर रहा हूं।

from PIL import Image
try:
    im=Image.open(filename)
    # do stuff
except IOError:
    # filename not an image file

हालांकि, जब यह पर्याप्त रूप से अधिकांश मामलों को कवर करता है, तो कुछ छवि फ़ाइलों जैसे, xcf, svg और psd का पता नहीं लगाया जा रहा है। Psd फ़ाइलें एक ओवरफ़्लोयर्स अपवाद को फेंकता है।

क्या कोई है जो मैं उन्हें भी शामिल कर सकता हूं?


21
विभिन्न भाषाओं में डुप्लिकेट को बंद करना विशेष रूप से आम बात नहीं है। यदि आप इस अवकाश के साथ किसी भी अन्य पायथन प्रश्न को नहीं खोल सकते हैं तो यह अजगर-विशिष्ट समाधान हो सकता है जिसे लोग पोस्ट करना चाहते हैं जो आपके द्वारा पोस्ट किए गए प्रश्न के लिए नहीं बना था।
पाओलो बरगीनो

हां, सबसे पहले मैं वास्तव में एक अजगर के लिए आशा कर रहा था, जो मुझे पता नहीं था: पी और फिर जैसा कि बेन ने कहा, बस जादुई संख्या पूरी छवि को मान्य नहीं करती है।
सुजॉय

जब तक आपके पास पहले से ही इसकी एक प्रति नहीं है, तब तक पूरी छवि को सत्यापित करना @Sujoy लगभग असंभव है, क्योंकि कंप्यूटर एक सही रंग पिक्सेल और 1s और 0s के एक गारबाइड सेट के बीच का अंतर नहीं बता सकता है, जब तक कि सभी नियंत्रण। (मैजिक नंबर) सही हैं।
डेविन बी

@devinb, सहमत, मैं सिर्फ मैजिक नंबर प्राप्त करूंगा और उसके साथ किया जाऊंगा जब तक कि कोई दूसरा किसी रिफ्लेक्टर के लिए कॉल करने के लिए बेहतर तरीके से न आ जाए :)
Sujoy

xcf और psd वास्तव में छवियां नहीं हैं, वे परियोजना फाइलें हैं जिनमें (अक्सर कई) छवियां होती हैं ... आप शायद svg के लिए एक मामला बना सकते हैं।
मंगल

जवाबों:


11

कई बार पहले युगल वर्ण विभिन्न फ़ाइल स्वरूपों के लिए एक जादुई संख्या होंगे। आप ऊपर अपवाद जाँच के अलावा इसके लिए जाँच कर सकते हैं।


10
यदि वह "वैध" छवियों के लिए वास्तव में परीक्षण कर रहा है तो यह पर्याप्त नहीं होगा; एक जादू की संख्या की उपस्थिति की गारंटी नहीं है कि फ़ाइल को छोटा नहीं किया गया है, उदाहरण के लिए।
बेन ब्लैंक

1
उत्कृष्ट सलाह, अब मुझे केवल यह पता लगाने की आवश्यकता है कि वे संख्याएँ क्या हैं। धन्यवाद :)
सुजॉय

@, ouch मैं नहीं सोचा था कि अभी तक। वास्तव में एक अच्छा बिंदु है
सुजॉय

@, आप किसी लाइब्रेरी से यह उम्मीद कैसे करेंगे कि किसी फाइल को छोटा किया गया है?
डेविन बी

6
@ ब्लेंक: सच है, लेकिन 99% समस्या को हल करना अक्सर बेहतर होता है, फिर इसे हल नहीं करना।
ब्रायन आर बॉडी

206

मुझे अभी-अभी बिलिन इमघ्र मॉड्यूल मिला है । अजगर प्रलेखन से:

Imghdr मॉड्यूल एक फ़ाइल या बाइट स्ट्रीम में निहित छवि के प्रकार को निर्धारित करता है।

यह इस तरह काम करता है:

>>> import imghdr
>>> imghdr.what('/tmp/bass')
'gif'

एक मॉड्यूल का उपयोग करना समान कार्यक्षमता को फिर से लागू करने से बेहतर है


2
हाँ imghdr सबसे छवि प्रारूपों के लिए काम करता है लेकिन सभी नहीं। svg, xcf और psd फाइलों के साथ मेरी मूल समस्या के अनुसार, अच्छी तरह से उन लोगों में imgdr के रूप में अच्छी तरह से undetected हैं
Sujoy

2
आपका उत्तर वास्तव में बेहतर है, धन्यवाद। जैसे ऊपर किसी ने कहा ... लेकिन एक समस्या को हल करने का 99% तरीका अक्सर बेहतर होता है, फिर इसे हल करना बिल्कुल भी नहीं ..
RinkyPinku

2
ध्यान देने योग्य बात: अगर imghdr.what(path)रिटर्न Noneदिया गया pathहै तो मान्यता प्राप्त छवि फ़ाइल प्रकार नहीं है। सूची : वर्तमान में मान्यता प्राप्त छवि प्रकार की आरजीबी , gif , पीबीएम , PGM , पीपीएम , टिफ , आरएएसटी , XBM , jpeg , bmp , png , webp , EXR
patryk.beza

1
सावधान रहे! एक वैध एचडीआर का मतलब एक वैध छवि नहीं है (उदाहरण के लिए इमेज बाइट्स में हाथापाई हो सकती है!)
फिलिप्पो मज़ज़ा

1
@FilippoMazza की टिप्पणी के अनुसार, मैं इस बात की पुष्टि कर सकता हूं कि स्थानांतरण के दौरान कट गई खराब छवि इस परीक्षा को पास कर सकती है, लेकिन जब पीआईएल इसे पढ़ने की कोशिश करेगा तो टूट जाएगा।
केविंमिक्

47

ब्रायन क्या सुझाव दे रहा है इसके अलावा आप पीआईएल की सत्यापित विधि का उपयोग कर सकते हैं कि फाइल टूटी है या नहीं।

im.verify ()

यह निर्धारित करने का प्रयास किया जाता है कि क्या वास्तव में छवि डेटा को डिकोड किए बिना फ़ाइल टूट गई है। यदि इस पद्धति में कोई समस्या है, तो यह उपयुक्त अपवादों को उठाता है। यह विधि केवल एक नई खुली छवि पर काम करती है; यदि छवि पहले ही लोड हो चुकी है, तो परिणाम अपरिभाषित है। साथ ही, यदि आपको इस पद्धति का उपयोग करने के बाद छवि को लोड करने की आवश्यकता है, तो आपको छवि फ़ाइल को फिर से खोलना होगा। गुण


अच्छी तरह से मुख्य समस्या यह है कि svg, xcf और psd फाइलें Image.open () के साथ नहीं खोली जा सकती हैं, इसलिए im.verify () के साथ सत्यापन का कोई मौका नहीं है
Sujoy

16
मेरे भगवान PIL दस्तावेज भयानक है। वास्तव में "उपयुक्त अपवाद" क्या है?
टिम्मम

यहां Image.verify () के लिए पिलो डॉक्यूमेंटेशन का लिंक दिया गया है । दुर्भाग्य से, यह बेहतर नहीं है, और ऐसा लगता है कि उन्होंने कुछ भी जोड़ने के बिना पैराग्राफ को ऊपर उठा दिया।
दो-बिट अल्केमिस्ट

मैंने भ्रष्ट पीएनजी फाइलों के लिए सिंटेक्सएयर को सत्यापित करते हुए देखा है
कार्ल

क्या "छवि डेटा को वास्तव में डिकोड करने के साथ" सत्यापित करने का कोई तरीका है?
ट्रेवर बॉयड स्मिथ

7

इसके अतिरिक्त PILइमेज चेक में आप फ़ाइल नाम एक्सटेंशन चेक भी जोड़ सकते हैं:

filename.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))

ध्यान दें कि यह केवल जाँचता है कि फ़ाइल नाम में एक वैध छवि एक्सटेंशन है या नहीं, यह वास्तव में यह देखने के लिए छवि को नहीं खोलता है कि क्या यह एक वैध छवि है, इसलिए आपको PILअन्य उत्तरों में सुझाए गए पुस्तकालयों में से किसी एक या अतिरिक्त का उपयोग करने की आवश्यकता है।


क्या होगा अगर एक्सटेंशन फाइलों में गलत हैं? जैसे, एक टेक्स्ट फ़ाइल .jpg एक्सटेंशन या इसके विपरीत के साथ सहेजी जाती है।
hafiz031 4

1
@ hafiz031 वास्तविक स्वरूप को प्राप्त करने के लिए आप इसे कर सकते हैं from PIL import Image img = Image.open(filename) print(img.format)और फिर इसे इस तरह से चेक कर सकते हैं :img.format.lower() in ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']
tsveti_iko

दुर्भाग्य से यह मेरे लिए काम नहीं किया। यह अभी भी एक JPEG छवि के रूप में एक दूषित छवि की पहचान कर रहा है। अंत में मैं इस मामले को इस तरह से संभालने में कामयाब रहा (मैं
OpenCv

6

अपडेट करें

मैंने अपनी पाइथन लिपि में निम्न समाधान को GitHub पर यहां लागू किया ।

मैंने यह भी सत्यापित किया है कि क्षतिग्रस्त फ़ाइलें (jpg) अक्सर 'टूटी हुई' छवियां नहीं होती हैं, यानी क्षतिग्रस्त तस्वीर फ़ाइल कभी-कभी एक वैध चित्र फ़ाइल बनी रहती है, मूल छवि खो जाती है या बदल जाती है, लेकिन आप अभी भी इसे बिना किसी त्रुटि के लोड करने में सक्षम हैं। लेकिन, फ़ाइल ट्रंकेशन हमेशा त्रुटियों का कारण बनता है।

अंत अद्यतन

एक फ़ाइल वैध और अक्षुण्ण छवि फ़ाइल है यह जाँचने के लिए, आप अधिकांश छवि प्रारूपों के साथ पायथन पिलो (PIL) मॉड्यूल का उपयोग कर सकते हैं ।

यदि आप टूटी हुई छवियों का पता लगाने का लक्ष्य रखते हैं, तो @Nadia Alramli सही तरीके से im.verify()विधि का सुझाव देता है, लेकिन यह सभी संभावित छवि दोषों काim.verify पता नहीं लगाता है , उदाहरण के लिए, काट-छाँट वाली छवियों का पता नहीं लगाता है (जो कि अधिकांश दर्शक अक्सर प्रभावित क्षेत्र के साथ लोड होते हैं)।

तकिया इस प्रकार के दोषों का भी पता लगाने में सक्षम है, लेकिन आपको चेक को ट्रिगर करने के लिए छवि हेरफेर या छवि डीकोड / रीकोड लागू करना होगा। अंत में मैं इस कोड का उपयोग करने का सुझाव देता हूं:

try:
  im = Image.load(filename)
  im.verify() #I perform also verify, don't know if he sees other types o defects
  im.close() #reload is necessary in my case
  im = Image.load(filename) 
  im.transpose(PIL.Image.FLIP_LEFT_RIGHT)
  im.close()
except: 
  #manage excetions here

छवि दोष के मामले में यह कोड एक अपवाद बढ़ाएगा। कृपया विचार करें कि im.verify छवि हेरफेर करने की तुलना में लगभग 100 गुना तेज है (और मुझे लगता है कि फ्लिप सस्ता परिवर्तनों में से एक है)। इस कोड के साथ आप मानक तकिए के साथ लगभग 10 एमबीटी / सेकेंड पर छवियों के एक सेट को सत्यापित करने जा रहे हैं या पिलो-सिमडी मॉड्यूल (आधुनिक 2.5 जीएचजेड x86_64 सीपीयू) के साथ 40 एमबीटी / सेकंड सेक।

अन्य प्रारूपों के लिए PSD , XCF , .. आप उपयोग कर सकते ImageMagick आवरण वैंड , कोड के रूप में इस प्रकार है:

im = wand.image.Image(filename=filename)
temp = im.flip;
im.close()

लेकिन, मेरे प्रयोगों से वांड की छंटनी की गई छवियों का पता नहीं चलता, मुझे लगता है कि यह बिना किसी संकेत के ग्रेयर्ड क्षेत्र के रूप में भागों की कमी है।

मैं यह बताता हूं कि Imagemagick के पास एक बाहरी कमांड की पहचान है जो काम कर सकती है , लेकिन मुझे उस फ़ंक्शन को प्रोग्रामेटिक रूप से लागू करने का कोई तरीका नहीं मिला है और मैंने इस मार्ग का परीक्षण नहीं किया है।

मैं हमेशा एक प्रारंभिक जांच करने का सुझाव देता हूं, फाइलों को शून्य (या बहुत छोटा) नहीं होने की जांच करें, एक बहुत सस्ता विचार है:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case

5

लिनक्स पर, आप पाइथन-मैजिक ( http://pypi.python.org/pypi/python-magic/0.1 ) का उपयोग कर सकते हैं, जो फ़ाइल स्वरूपों की पहचान करने के लिए कामवासना का उपयोग करता है।

AFAIK, libmagic फाइल में दिखता है और आपको बिटमैप आयामों, प्रारूप संस्करण आदि जैसे प्रारूप के बजाय इसके बारे में अधिक बताने की कोशिश करता है। इसलिए आप इसे "वैधता" के लिए एक सतही परीक्षा के रूप में देख सकते हैं।

"मान्य" की अन्य परिभाषाओं के लिए आपको अपने परीक्षण लिखने पड़ सकते हैं।


5

आप पायथन बाइंडिंग का उपयोग libworking, अजगर-जादू के लिए कर सकते हैं और फिर माइम प्रकारों की जांच कर सकते हैं। यह आपको नहीं बताएगा कि फाइलें दूषित हैं या बरकरार हैं लेकिन यह निर्धारित करने में सक्षम होना चाहिए कि यह किस प्रकार की छवि है।


3

वैसे, मैं psd के इनसाइड्स के बारे में नहीं जानता, लेकिन मुझे यकीन है, यह पता है, तथ्य की बात के रूप में, svg प्रति से एक छवि फ़ाइल नहीं है, - यह xml पर आधारित है, इसलिए यह अनिवार्य रूप से, एक है सादा पाठ फ़ाइल।


अहा, तुम सही हो। यह xml है। हालाँकि, इसमें कुछ छवि डेटा शामिल हैं।
सुजॉय

2

एक विकल्प filetypeपैकेज का उपयोग करना है।

स्थापना

python -m pip install filetype

लाभ

  1. त्वरित: अपनी छवि के पहले कुछ बाइट्स लोड करके अपना काम करता है ( जादू नंबर पर जांच करें )
  2. विभिन्न माइम प्रकार का समर्थन करता है: छवियाँ, वीडियो, फ़ॉन्ट्स, ऑडियो, अभिलेखागार।

समाधान उदाहरण

import filetype

filename = "/path/to/file.jpg"

if filetype.image(filename):
    print(f"{filename} is a valid image...")
elif filetype.video(filename):
    print(f"{filename} is a valid video...")

आधिकारिक रिपो पर अतिरिक्त जानकारी: https://github.com/h2non/filetype.py


1

फ़ाइल एक्सटेंशन की जाँच स्वीकार्य होगी या क्या आप डेटा की पुष्टि करने की कोशिश कर रहे हैं जो एक छवि फ़ाइल का प्रतिनिधित्व करता है?

यदि आप फ़ाइल एक्सटेंशन को एक नियमित अभिव्यक्ति की जांच कर सकते हैं या एक साधारण तुलना आवश्यकता को पूरा कर सकती है।


बस विस्तार की जाँच नहीं होगी, क्योंकि एक jpg या कुछ के रूप में एक txt फ़ाइल का नाम बदल सकता है। मुझे लगता है, अगर मुझे कोई समाधान नहीं मिल रहा है, तो ही मैं xcf और svg के लिए एक्सटेंशन चेकिंग का उपयोग करूंगा
Sujoy

समझ में आता है, मैं कुछ स्पष्टीकरण के लिए उम्मीद कर रहा था इससे पहले कि मैं एक समाधान तैयार करने के लिए आगे बढ़ूं जो आपकी आवश्यकताओं के अनुरूप बेहतर हो। धन्यवाद!
doomspork

-1
format = [".jpg",".png",".jpeg"]
 for (path,dirs,files) in os.walk(path):
     for file in files:
         if file.endswith(tuple(format)):
             print(path)
             print ("Valid",file)
         else:
             print(path)
             print("InValid",file)

आपके कोड में कुछ इंडेंटेशन समस्याएँ हैं और वे ठीक से नहीं चलेंगे। इसके अलावा, इस बारे में कुछ स्पष्टीकरण जोड़ने पर विचार करें कि आपका कोड समस्या का समाधान क्यों और कैसे करता है। भविष्य में आने वाले पाठकों के लिए कोड-केवल उत्तर इतने उपयोगी नहीं हैं।
टोमेरिकू

यहाँ हमने अग्रपर विधि का उपयोग किया है।
rObinradOO
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.