Bir dosyanın geçerli bir resim dosyası olup olmadığı nasıl kontrol edilir?


106

Şu anda PIL kullanıyorum.

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

Bununla birlikte, bu çoğu durumu yeterince kapsasa da, xcf, svg ve psd gibi bazı görüntü dosyaları algılanmamaktadır. Psd dosyaları bir OverflowError istisnası atar.

Bunları da dahil edebileceğim bir yol var mı?


21
Farklı dillerdeki kopyaları kapatmak pek yaygın bir uygulama değildir. Bununla birlikte başka herhangi bir Python sorusu bulamazsanız, açık bırakın, çünkü gönderdiğiniz soruya ulaşmayan, insanların göndermek isteyeceği Python'a özgü çözümler olabilir.
Paolo Bergantino

evet, her şeyden önce gerçekten bilmediğim bir python lib'i umuyordum: P ve sonra ben'in işaret ettiği gibi, sadece sihirli sayılar tüm görüntüyü doğrulamıyor.
Sujoy

@Sujoy, halihazırda bir kopyasına sahip değilseniz, tüm bir görüntünün doğrulanması neredeyse imkansızdır çünkü bilgisayar, tüm kontrol (sihirli sayılar) doğru.
DevinB

@devinb, kabul etti, başka biri refaktör çağırmak için daha iyi bir şey bulmadıkça sadece sihirli sayıları alacağım ve onunla işim bitecek :)
Sujoy

xcf ve psd gerçekte resim değillerdir, bunlar (genellikle çok sayıda) resim içeren proje dosyalarıdır ... muhtemelen svg için bir durum yaratabilirsiniz.
mgalgs

Yanıtlar:


11

Çoğu zaman ilk çift karakter çeşitli dosya formatları için sihirli bir sayı olacaktır. Yukarıdaki istisna kontrolünüze ek olarak bunu kontrol edebilirsiniz.


11
Gerçekten "geçerli" görüntüleri test ediyorsa bu yeterli olmayacaktır; örneğin sihirli bir sayının varlığı dosyanın kesilmediğini garanti etmez.
Ben Blank

1
mükemmel bir tavsiye, şimdi sadece bu sayıların ne olduğunu bulmam gerekiyor. teşekkürler :)
Sujoy

@ben, ouch henüz bunu düşünmedim. bu gerçekten iyi bir nokta
Sujoy

@Ben, bir kütüphanenin bir dosyanın kesildiğini anlamasını nasıl beklersiniz?
DevinB

6
@Ben Blank: Doğru, ancak bir problemi çözmek, yolun% 99'unu çözmekten genellikle daha iyidir.
Brian R. Bondy

208

Yerleşik imghdr modülünü buldum . Python belgelerinden:

İmghdr modülü, bir dosya veya bayt akışında bulunan görüntünün türünü belirler.

Bu nasıl çalışır:

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

Bir modül kullanmak, benzer işlevselliği yeniden uygulamaktan çok daha iyidir


2
yes imghdr çoğu resim formatı için çalışır ama hepsi için değil. svg, xcf ve psd dosyalarıyla ilgili orijinal sorunuma göre, bunlar imghdr'de de algılanmıyor
Sujoy

2
Cevabınız aslında daha iyi, teşekkürler. Yukarıda birinin söylediği gibi ... ama bir problemi çözmek çoğu zaman onu
çözmemek yerine

2
Unutulmaması gereken: verilen tanınmayan görüntü dosyası türü ise imghdr.what(path)döner . Liste : Şu anda tanınan resim türünden rgb , gif , PBM , PGM , ppm , tiff , rast , XBM , jpeg , bmp , png , WebP , EXR . Nonepath
patryk.beza

1
Dikkatli ol! Geçerli bir hdr, geçerli bir görüntü anlamına gelmez (örneğin, görüntü baytları karıştırılmış olabilir!)
Filippo Mazza

1
@FilippoMazza'nın yorumuna göre, aktarım sırasında kesilen kötü bir görüntünün bu testi geçebileceğini, ancak PIL onu okumaya çalıştığında kırılacağını doğrulayabilirim.
kevinmicke

47

Brian'ın önerdiğine ek olarak , dosyanın bozuk olup olmadığını kontrol etmek için PIL'in doğrulama yöntemini kullanabilirsiniz.

im.verify ()

Görüntü verilerinin kodunu gerçekten çözmeden dosyanın bozuk olup olmadığını belirlemeye çalışır. Bu yöntem herhangi bir sorun bulursa uygun istisnaları ortaya çıkarır. Bu yöntem yalnızca yeni açılan bir görüntü üzerinde çalışır; görüntü zaten yüklenmişse, sonuç tanımsızdır. Ayrıca, bu yöntemi kullandıktan sonra görüntüyü yüklemeniz gerekirse, görüntü dosyasını yeniden açmanız gerekir. Öznitellikler


asıl sorun svg, xcf ve psd dosyalarının Image.open () ile açılamaması, dolayısıyla im.verify () ile doğrulama şansı yok
Sujoy

16
Tanrım, PIL belgeleri korkunç. "Uygun bir istisna" tam olarak nedir?
Timmmm

Image.verify () için Yastık belgelerine bağlantı burada . Ne yazık ki, daha iyi değil ve görünen o ki yukarıdaki paragrafı hiçbir şey eklemeden kaldırmışlar.
İki Bit Simyacı

Bozuk png dosyaları için SyntaxError yükseltmesini doğruladım
Carl

"Görüntü verilerinin kodunu çözerek" doğrulamanın bir yolu var mı?
Trevor Boyd Smith

7

PILGörüntü kontrolüne ek olarak, aşağıdaki gibi dosya adı uzantısı kontrolü de ekleyebilirsiniz:

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

Bunun yalnızca dosya adının geçerli bir resim uzantısı olup olmadığını kontrol ettiğini, geçerli bir resim olup olmadığını görmek için resmi açmadığını, bu nedenle ek olarak PILveya diğer yanıtlarda önerilen kitaplıklardan birini kullanmanız gerektiğini unutmayın .


Dosyalardaki uzantılar yanlışsa ne olur? Örneğin, bir metin dosyası .jpg uzantısıyla kaydedilir veya tam tersi.
hafiz031

1
@ hafiz031 Asıl formatı elde etmek için yapıp şu şekilde from PIL import Image img = Image.open(filename) print(img.format)kontrol edebilirsiniz :img.format.lower() in ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']
tsveti_iko

Ne yazık ki bu benim için işe yaramadı. Hala bozuk bir görüntüyü bir JPEG görüntüsü olarak tanımlıyor. Sonunda bu durumu şu şekilde ele almayı başardım (OpenCv kullanıyorum): stackoverflow.com/a/63421847/6907424
hafiz031

6

Güncelleme

Ayrıca GitHub'daki Python betiğimde aşağıdaki çözümü uyguladım .

Ayrıca hasarlı dosyaların (jpg) sıklıkla 'bozuk' resimler olmadığını doğruladım, yani hasarlı bir resim dosyası bazen okunaklı bir resim dosyası olarak kalır, orijinal resim kaybolur veya değiştirilir, ancak yine de hata olmadan yükleyebilirsiniz. Ancak, dosya kesme her zaman hatalara neden olur.

Güncellemeyi Sonlandır

Bir dosyanın geçerli ve bozulmamış bir görüntü dosyası olup olmadığını kontrol etmek için çoğu görüntü formatıyla Python Yastık (PIL) modülünü kullanabilirsiniz .

Bozuk görüntüleri de algılamayı hedeflediğinizde, @Nadia Alramli im.verify()yöntemi doğru bir şekilde önerir , ancak bu , tüm olası görüntü kusurlarınıim.verify algılamaz , örneğin kesilmiş görüntüleri algılamaz (çoğu izleyici genellikle gri bir alanla yüklenir).

Yastık bu tür kusurları da algılayabilir, ancak görüntü işleme veya görüntü kod çözme / yeniden kodlama uygulamanız veya kontrolü tetiklemeniz gerekir. Son olarak şu kodu kullanmanızı öneririm:

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

Görüntü kusurları durumunda bu kod bir istisna oluşturacaktır. Lütfen im.verify'ın görüntü işlemeyi gerçekleştirmekten yaklaşık 100 kat daha hızlı olduğunu göz önünde bulundurun (ve bence çevirme daha ucuz dönüşümlerden biridir). Bu kodla, standart Yastık ile yaklaşık 10 MByte / sn veya Pillow-SIMD modülü (modern 2.5Ghz x86_64 CPU) ile 40 MByte / sn hızında bir dizi görüntüyü doğrulayacaksınız.

Diğer formatlar için psd , xcf , .. kullanabileceğiniz ImageMagick'in sarıcı Wand , kod aşağıdaki gibi olduğu:

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

Ancak deneylerime göre, Değnek kesilmiş görüntüleri algılamıyor, bence eksik parçaları, sormadan gri alan olarak yüklüyor.

Bunu kırmızı Imagemagick harici komut vardır tanımlamak o olabilir işi yapmak ama programlı o fonksiyonu çağırmak için bir yol bulmuş değil ve ben bu rotayı test etmedim.

Her zaman bir ön kontrol yapmanızı , dosya boyutunun sıfır (veya çok küçük) olup olmadığını kontrol etmenizi öneririm , çok ucuz bir fikirdir:

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

5

Linux'ta, dosya biçimlerini tanımlamak için libmagic kullanan python-magic ( http://pypi.python.org/pypi/python-magic/0.1 ) kullanabilirsiniz .

AFAIK, libmagic dosyaya bakar ve size sadece formattan çok, bitmap boyutları, format versiyonu vb. Gibi daha fazlasını anlatmaya çalışır. Dolayısıyla bunu "geçerlilik" için yüzeysel bir test olarak görebilirsiniz.

"Geçerli" nin diğer tanımları için kendi testlerinizi yazmanız gerekebilir.


5

Python bağlamalarını libmagic, python-magic için kullanabilir ve ardından mime türlerini kontrol edebilirsiniz. Bu, dosyaların bozuk veya sağlam olup olmadığını size söylemez, ancak ne tür bir görüntü olduğunu belirleyebilmelidir.


3

Pekala, psd'nin içini bilmiyorum, ama eminim ki, aslında svg'nin kendi başına bir görüntü dosyası olmadığını biliyorum - xml'ye dayanıyor, bu yüzden aslında bir düz metin dosyası.


aha, haklısın. xml'dir. ancak, içine gömülü bazı görüntü verilerini içerir.
Sujoy

3

Bir seçenek, filetypepaketi kullanmaktır .

Kurulum

python -m pip install filetype

Avantajları

  1. Hızlı: Görüntünüzün ilk birkaç baytını yükleyerek çalışır ( sihirli numarayı kontrol edin )
  2. Farklı mime türlerini destekler: Görüntüler, Videolar, Yazı Tipleri, Ses, Arşivler.

Çözüm örneği

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...")

Resmi depoya ilişkin ek bilgiler: https://github.com/h2non/filetype.py


1

Dosya uzantılarını kontrol etmek kabul edilebilir mi yoksa verilerin kendisinin bir resim dosyasını temsil ettiğini mi doğrulamaya çalışıyorsunuz?

Dosya uzantısını kontrol edebiliyorsanız, bir normal ifade veya basit bir karşılaştırma gereksinimi karşılayabilir.


bir txt dosyasını jpg veya başka bir şey olarak yeniden adlandırabildiğinden, uzantıyı kontrol etmek yeterli olmaz. sanırım, eğer bir çözüm bulamazsam, ancak o zaman xcf ve svg için uzantı kontrolünü kullanacağım
Sujoy,

Anlaşılır, ihtiyaçlarınıza daha uygun bir çözüm bulmaya başlamadan önce biraz açıklama bekliyordum. Teşekkürler!
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)

Kodunuzda bazı girinti sorunları var ve düzgün çalışmıyor. Ayrıca, kodunuzun sorunu neden ve nasıl çözdüğüne dair bazı açıklamalar eklemeyi düşünün. Buraya gelecek okuyucular için bu kadar yararlı olmayacak şekilde yalnızca kod yanıtları.
Tomerikoo

Burada Agrparser yöntemini kullandık.
rObinradOO
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.