9

I'm using ImageMagick (with Wand in Python) to convert images and to get thumbnails from them. However, I noticed that I need to verify whether a file is an image or not ahead of time. Should I do this with Identify?

So I would assume checking the integrity of a file needs the whole file to be read into memory. Is it better to try and convert the file and if there was an error, then we know the file wasn't good.

Falko
  • 17,076
  • 13
  • 60
  • 105
Kiarash
  • 7,378
  • 10
  • 44
  • 69

5 Answers5

15

seems like you answered your own question

$ ls -l *.png
-rw-r--r-- 1 jsp jsp 526254 Jul 20 12:10 image.png
-rw-r--r-- 1 jsp jsp  10000 Jul 20 12:12 image_with_error.png
$ identify image.png &> /dev/null; echo $?
0
$ identify image_with_error.png &> /dev/null; echo $?
0
$ convert image.png /dev/null &> /dev/null ; echo $?
0
$ convert image_with_error.png /dev/null &> /dev/null ; echo $?
1
jsp
  • 1,225
  • 11
  • 21
  • 3
    Here's another solution using identify, but without convert: `identify -verbose *.png 2>&1 | grep "corrupt image"` `identify: corrupt image 'image_with_error.png' @ error/png.c/ReadPNGImage/4051.` – Artem Russakovskii Nov 10 '17 at 20:04
  • 2
    @ArtemRussakovskii `identify -verbose *.png 2>&1 | grep "error"` would be better. I have a lot of files that don't have any "corrupt image" texts in the output from identify – phuclv Feb 12 '19 at 03:07
  • 2
    `identify -verbose image.png` will actually exit with a `1` code if it has any errors. No need to grep. You can then check stderr. Gotcha is that it exits with `0` if you don't include the `-verbose` flag. – Alec Jan 28 '20 at 10:29
  • If it is jpeg, we can use `jpeg -c`. Both `identify -verbose` and `magick ...` *will* show the corrupted messages, but *will not* exit with code 1 (just 0). – midnite Apr 10 '23 at 00:22
  • `ImageMagick 7.1.0-6 Q16-HDRI x64 2021-09-04` `magick identify "$badFile"` seems to set a status of 1 now, at least for my issue when I saw errors concerning `No IDATs written into file '....png' @ error/png.c/MagickPNGErrorHandler/1716`. `identify: Expected 8 bytes; found 0 bytes '...' @ warning/png.c/MagickPNGWarningHandler/1749.` `identify: Read Exception '...' @ error/png.c/MagickPNGErrorHandler/1716` – Pysis Apr 25 '23 at 18:37
10

if you specify the regard-warnings flag with the imagemagick identify tool

magick identify -regard-warnings myimage.jpg

it will throw an error if there are any warnings about the file. This is good for checking images, and seems to be a lot faster than using verbose.

stib
  • 3,346
  • 2
  • 30
  • 38
3

I the case you use Python you can consider also the Pillow module.

In my experiments, I have used both the Pyhton Pillow module (PIL) and the Imagemagick wrapper Wand (for psd, xcf formats) in order to detect broken images, the original answer with code snippets is here.

Update: I also implemented this solution in my Python script here on GitHub.

I also verified that damaged files (jpg) frequently are not 'broken' images i.e, a damaged picture file sometimes remains a legit picture file, the original image is lost or altered but you are still able to load it. End Update

I quote the full answer for completeness:

You can use Python Pillow(PIL) module, with most image formats, to check if a file is a valid and intact image file.

In the case you aim at detecting also broken images, @Nadia Alramli correctly suggests the im.verify() method, but this does not detect all the possible image defects, e.g., im.verify does not detect truncated images (that most viewers often load with a greyed area).

Pillow is able to detect these type of defects too, but you have to apply image manipulation or image decode/recode in or to trigger the check. Finally I suggest to use this code:

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

In case of image defects this code will raise an exception. Please consider that im.verify is about 100 times faster than performing the image manipulation (and I think that flip is one of the cheaper transformations). With this code you are going to verify a set of images at about 10 MBytes/sec (using single thread of a modern 2.5Ghz x86_64 CPU).

For the other formats psd,xcf,.. you can use Imagemagick wrapper Wand, the code is as follows:

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

But, from my experiments Wand does not detect truncated images, I think it loads lacking parts as greyed area without prompting.

I red that Imagemagick has an external command identify that could make the job, but I have not found a way to invoke that function programmatically and I have not tested this route.

I suggest to always perform a preliminary check, check the filesize to not be zero (or very small), is a very cheap idea:

statfile = os.stat(filename)
filesize = statfile.st_size
if filesize == 0:
  #manage here the 'faulty image' case
Fabiano Tarlao
  • 3,024
  • 33
  • 40
1

Here's another solution using identify, but without convert:

identify -verbose *.png 2>&1 | grep "corrupt image"

identify: corrupt image 'image_with_error.png' @ error/png.c/ReadPNGImage/4051.

Artem Russakovskii
  • 21,516
  • 18
  • 92
  • 115
  • 1
    I verified that identify only perform quick check, I suppose on the file header infos.. it does not check the integrity of the data itself. – Fabiano Tarlao Dec 10 '18 at 10:08
-2

i use identify:

$ identify image.tif
00000005.tif TIFF 4741x6981 4741x6981+0+0 8-bit DirectClass 4.471MB 0.000u 0:00.010
$ echo $?