Bagaimana cara memeriksa apakah suatu file adalah file gambar yang valid?


105

Saya saat ini menggunakan PIL.

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

Namun, meskipun ini cukup mencakup sebagian besar kasus, beberapa file gambar seperti, xcf, svg dan psd tidak terdeteksi. File Psd menampilkan pengecualian OverflowError.

Apakah ada cara agar saya bisa memasukkannya juga?


21
Ini bukan praktik umum untuk menutup duplikat di berbagai bahasa. Jika Anda tidak dapat menemukan pertanyaan Python lain dengan ini, biarkan terbuka karena mungkin ada solusi khusus Python yang ingin diposting orang yang tidak sesuai dengan pertanyaan yang Anda posting.
Paolo Bergantino

ya, pertama-tama saya benar-benar berharap untuk lib python yang tidak saya ketahui: P dan kemudian seperti yang ditunjukkan ben, hanya angka ajaib yang tidak memvalidasi seluruh gambar.
Sujoy

@Sujoy, memvalidasi seluruh gambar hampir tidak mungkin, kecuali Anda sudah memiliki salinannya, karena komputer tidak dapat membedakan antara piksel warna yang benar, dan kumpulan 1 dan 0 yang kacau, selama semua kontrol (angka ajaib) benar.
DevinB

@devinb, setuju, saya hanya akan mendapatkan nomor ajaib dan selesai dengan itu kecuali orang lain datang dengan sesuatu yang lebih baik untuk memanggil refactor :)
Sujoy

xcf dan psd sebenarnya bukan gambar, mereka adalah file proyek yang berisi (seringkali banyak) gambar ... Anda mungkin bisa membuat kasus untuk svg.
mgalgs

Jawaban:


11

Sering kali karakter pasangan pertama akan menjadi angka ajaib untuk berbagai format file. Anda dapat memeriksa ini selain pemeriksaan pengecualian Anda di atas.


10
Itu tidak akan cukup jika dia benar-benar menguji gambar yang "valid"; Kehadiran angka ajaib tidak menjamin bahwa file tersebut belum terpotong, misalnya.
Ben Blank

1
saran yang sangat baik, sekarang saya hanya perlu mencari tahu apa angka-angka itu. terima kasih :)
Sujoy

@ ben, aduh saya belum memikirkan itu. itu memang poin yang bagus
Sujoy

@ Ben, bagaimana Anda mengharapkan perpustakaan menyimpulkan file telah terpotong?
DevinB

6
@ Ben Blank: Benar, tetapi memecahkan masalah 99% sering kali lebih baik daripada tidak menyelesaikannya sama sekali.
Brian R. Bondy

206

Saya baru saja menemukan modul imghdr bawaan . Dari dokumentasi python:

Modul imghdr menentukan jenis gambar yang terdapat dalam file atau aliran byte.

Begini Cara kerjanya:

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

Menggunakan modul jauh lebih baik daripada menerapkan kembali fungsionalitas serupa


2
ya imghdr berfungsi untuk sebagian besar format gambar, tetapi tidak semua. sesuai masalah asli saya dengan file svg, xcf dan psd, nah itu juga tidak terdeteksi di imghdr
Sujoy

2
Jawaban Anda sebenarnya lebih baik, terima kasih. Seperti yang dikatakan seseorang di atas ... tetapi memecahkan masalah 99% sering kali lebih baik daripada tidak menyelesaikannya sama sekali ..
RinkyPinku

2
Patut dicatat: imghdr.what(path)mengembalikan Nonejika diberikan pathjenis file gambar yang tidak dikenali. Daftar jenis saat ini diakui image: rgb , gif , pbm , PGM , ppm , tiff , rast , xbm , jpeg , bmp , png , webp , EXR .
patryk.beza

1
Hati-hati! Hdr yang valid tidak berarti gambar yang valid (misalnya, byte gambar mungkin telah diacak!)
Filippo Mazza

1
Berdasarkan komentar @FilippoMazza, saya dapat memastikan bahwa gambar buruk yang terpotong selama transfer dapat lulus tes ini, tetapi akan rusak ketika PIL mencoba membacanya.
kevinmicke

47

Selain apa yang disarankan Brian, Anda dapat menggunakan metode verifikasi PIL untuk memeriksa apakah file rusak.

im.verify ()

Upaya untuk menentukan apakah file rusak, tanpa benar-benar mendekode data gambar. Jika metode ini menemukan masalah, metode ini memunculkan pengecualian yang sesuai. Metode ini hanya berfungsi pada gambar yang baru dibuka; jika gambar sudah dimuat, hasilnya tidak terdefinisi. Selain itu, jika Anda perlu memuat gambar setelah menggunakan metode ini, Anda harus membuka kembali file gambar tersebut. Atribut


Nah masalah utamanya adalah bahwa file svg, xcf dan psd tidak dapat dibuka dengan Image.open () oleh karena itu, tidak ada kesempatan untuk memverifikasi dengan im.verify ()
Sujoy

16
Ya Tuhan, dokumentasi PIL sangat buruk. Apa sebenarnya yang dimaksud dengan "pengecualian yang sesuai"?
Timmmm

Berikut link ke dokumentasi Pillow untuk Image.verify () . Sayangnya, ini tidak lebih baik, dan sepertinya mereka hanya mengangkat paragraf di atas tanpa menambahkan apapun.
Two-Bit Alchemist

Saya telah melihat verifikasi menaikkan SyntaxError untuk file png yang korup
Carl

apakah ada cara untuk memverifikasi "DENGAN benar-benar mendekode data gambar"?
Trevor Boyd Smith

7

Selain PILpemeriksaan gambar, Anda juga dapat menambahkan pemeriksaan ekstensi nama file seperti ini:

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

Perhatikan bahwa ini hanya memeriksa apakah nama file memiliki ekstensi gambar yang valid, itu tidak benar-benar membuka gambar untuk melihat apakah itu gambar yang valid, itulah mengapa Anda perlu menggunakan tambahan PILatau salah satu pustaka yang disarankan dalam jawaban lain.


Bagaimana jika ekstensi salah di file? Misalnya, file teks disimpan dengan ekstensi .jpg atau sebaliknya.
hafiz031

1
@ hafiz031 Untuk mendapatkan format yang sebenarnya Anda dapat melakukannya from PIL import Image img = Image.open(filename) print(img.format)dan kemudian memeriksanya seperti ini:img.format.lower() in ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif']
tsveti_iko

Sayangnya ini tidak berhasil untuk saya. Itu masih mengidentifikasi gambar yang rusak sebagai gambar JPEG. Akhirnya saya berhasil menangani kasus ini dengan cara ini (saya menggunakan OpenCv): stackoverflow.com/a/63421847/6907424
hafiz031

6

Memperbarui

Saya juga menerapkan solusi berikut dalam skrip Python saya di sini di GitHub .

Saya juga memverifikasi bahwa file yang rusak (jpg) seringkali bukan gambar yang 'rusak', misalnya file gambar yang rusak terkadang tetap menjadi file gambar yang sah, gambar asli hilang atau diubah tetapi Anda masih dapat memuatnya tanpa kesalahan. Namun, pemotongan file selalu menyebabkan error.

Akhiri Pembaruan

Anda dapat menggunakan modul Python Pillow (PIL), dengan sebagian besar format gambar, untuk memeriksa apakah suatu file adalah file gambar yang valid dan utuh.

Jika Anda bertujuan untuk mendeteksi gambar yang juga rusak, @Nadia Alramli menyarankan metodenya dengan benar im.verify(), tetapi ini tidak mendeteksi semua kemungkinan cacat gambar , misalnya, im.verifytidak mendeteksi gambar yang terpotong (yang sering dimuat oleh sebagian besar pemirsa dengan area berwarna abu-abu).

Pillow juga dapat mendeteksi jenis cacat ini, tetapi Anda harus menerapkan manipulasi gambar atau decode / pengodean ulang gambar atau untuk memicu pemeriksaan. Akhirnya saya menyarankan untuk menggunakan kode ini:

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

Jika gambar cacat, kode ini akan memunculkan pengecualian. Harap pertimbangkan bahwa im.verify sekitar 100 kali lebih cepat daripada melakukan manipulasi gambar (dan menurut saya flip adalah salah satu transformasi yang lebih murah). Dengan kode ini Anda akan memverifikasi sekumpulan gambar dengan kecepatan sekitar 10 MBytes / detik dengan Pillow standar atau 40 MBytes / detik dengan modul Pillow-SIMD (CPU 2.5Ghz x86_64 modern).

Untuk format lain psd , xcf , .. bisa menggunakan Imagemagick wrapper Wand , kodenya sebagai berikut:

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

Tapi, dari percobaan saya Wand tidak mendeteksi gambar yang terpotong, saya pikir itu memuat bagian yang kurang sebagai area abu-abu tanpa disuruh.

Saya merah bahwa Imagemagick memiliki identifikasi perintah eksternal yang dapat melakukan pekerjaan itu, tetapi saya belum menemukan cara untuk menjalankan fungsi itu secara terprogram dan saya belum menguji rute ini.

Saya sarankan untuk selalu melakukan pemeriksaan awal, periksa ukuran file menjadi tidak nol (atau sangat kecil), adalah ide yang sangat murah :

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

5

Di Linux, Anda dapat menggunakan python-magic ( http://pypi.python.org/pypi/python-magic/0.1 ) yang menggunakan libmagic untuk mengidentifikasi format file.

AFAIK, libmagic melihat ke dalam file dan mencoba memberi tahu Anda lebih banyak tentangnya daripada hanya formatnya, seperti dimensi bitmap, versi format, dll. Jadi, Anda mungkin melihat ini sebagai tes dangkal untuk "validitas".

Untuk definisi lain dari "valid", Anda mungkin harus menulis pengujian Anda sendiri.


5

Anda dapat menggunakan pengikatan Python ke libmagic, python-magic dan kemudian memeriksa jenis mime. Ini tidak akan memberi tahu Anda jika file rusak atau utuh tetapi harus dapat menentukan jenis gambar apa itu.


3

Yah, saya tidak tahu tentang bagian dalam psd, tapi saya, yakin, tahu bahwa, pada kenyataannya, svg bukanlah file gambar itu sendiri, - ini didasarkan pada xml, jadi pada dasarnya, a file teks biasa.


aha, kamu benar. itu xml. namun, ini berisi beberapa data gambar yang disematkan di dalamnya.
Sujoy

2

Salah satu opsinya adalah menggunakan filetypepaket.

Instalasi

python -m pip install filetype

Keuntungan

  1. Cepat: Melakukannya dengan memuat beberapa byte pertama dari gambar Anda ( periksa nomor ajaibnya )
  2. Mendukung jenis pantomim yang berbeda: Gambar, Video, Font, Audio, Arsip.

Contoh solusi

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

Informasi tambahan di repo resmi: https://github.com/h2non/filetype.py


1

Apakah memeriksa ekstensi file dapat diterima atau Anda mencoba memastikan bahwa data itu sendiri mewakili file gambar?

Jika Anda dapat memeriksa ekstensi file, ekspresi reguler atau perbandingan sederhana dapat memenuhi persyaratan.


hanya memeriksa ekstensi tidak cukup, karena seseorang dapat mengganti nama file txt sebagai jpg atau sesuatu. saya kira, jika saya tidak dapat menemukan solusi, hanya dengan demikian saya akan menggunakan pemeriksaan ekstensi untuk xcf dan svg
Sujoy

Bisa dimaklumi, saya hanya mengharapkan klarifikasi sebelum saya mulai merancang solusi yang mungkin lebih sesuai dengan kebutuhan Anda. Terima kasih!
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)

Kode Anda memiliki beberapa masalah indentasi dan tidak akan berfungsi dengan baik. Juga, pertimbangkan untuk menambahkan beberapa penjelasan tentang mengapa dan bagaimana kode Anda menyelesaikan masalah. Jawaban kode-saja tidak begitu membantu untuk pembaca mendatang yang datang ke sini.
Tomerikoo

Di sini kami telah menggunakan metode Agrparser.
rObinradOO
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.