I need to detect if the image file is corrupted in Java. I'm working only with PNG, JPG images. Is this possible to do with Sanselan? Or can it be done with ImageIO? I've tried using ImageIO.read seems like it works. But I'm not sure if it can detect every kind of errors in images. I'd like to know what's the best practice.
-
2I would suggest that the only way to detect *every* kind of error in an image (where "error" is defined as any discrepancy which causes imperfect behaviour) is to go ahead and use the image. It's entirely possible for an image to suffer a corruption which nonetheless results in a valid file, albeit one with "the wrong pixels". It may be useful to think very specifically about what it is you want to detect. – Andrzej Doyle Nov 07 '11 at 16:34
-
2ImageIO can detect truncated PNG with an exception thrown, but for JPG that is truncated, I can't get it to throw an exception. – Archimedes Trajano Apr 09 '12 at 05:04
-
Did you get any solution for this ? – Manu Jun 15 '15 at 08:48
4 Answers
Here is my solution that would handle checking for broken GIF, JPG and PNG. It checks for truncated JPEG using the JPEG EOF marker, GIF using an index out of bounds exception check and PNG using an EOFException
public static ImageAnalysisResult analyzeImage(final Path file)
throws NoSuchAlgorithmException, IOException {
final ImageAnalysisResult result = new ImageAnalysisResult();
final InputStream digestInputStream = Files.newInputStream(file);
try {
final ImageInputStream imageInputStream = ImageIO
.createImageInputStream(digestInputStream);
final Iterator<ImageReader> imageReaders = ImageIO
.getImageReaders(imageInputStream);
if (!imageReaders.hasNext()) {
result.setImage(false);
return result;
}
final ImageReader imageReader = imageReaders.next();
imageReader.setInput(imageInputStream);
final BufferedImage image = imageReader.read(0);
if (image == null) {
return result;
}
image.flush();
if (imageReader.getFormatName().equals("JPEG")) {
imageInputStream.seek(imageInputStream.getStreamPosition() - 2);
final byte[] lastTwoBytes = new byte[2];
imageInputStream.read(lastTwoBytes);
if (lastTwoBytes[0] != (byte)0xff || lastTwoBytes[1] != (byte)0xd9) {
result.setTruncated(true);
} else {
result.setTruncated(false);
}
}
result.setImage(true);
} catch (final IndexOutOfBoundsException e) {
result.setTruncated(true);
} catch (final IIOException e) {
if (e.getCause() instanceof EOFException) {
result.setTruncated(true);
}
} finally {
digestInputStream.close();
}
return result;
}
public class ImageAnalysisResult {
boolean image;
boolean truncated;
public void setImage(boolean image) {
this.image = image;
}
public void setTruncated(boolean truncated) {
this.truncated = truncated;
}
}
}

- 3,134
- 13
- 34
- 54

- 35,625
- 19
- 175
- 265
-
2Shouldn't the two clauses of the JPEG condition check be connected with logical OR instead of AND? – mnicky Mar 12 '15 at 12:03
-
-
-
1I built a little library based on this answer since I was in need as well! hope it may help: https://github.com/lamba92/KImageCheck – Lamberto Basti Mar 11 '19 at 10:23
If the image in JPEG, use this:
JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f));
decoder.produceImage();
if it throws an exception; this means the image is corrupted.
for the other cases; just use new ImageIcon(file)
to check the validity.

- 1,941
- 1
- 19
- 30
-
It works fine, if it is not valid jpeg image then it'll throw ImageFormatException. Is there any way to check whether mp4 file is corrupted or not ?? – Sumanth Varada May 15 '18 at 14:16
-
Use `PNGImageDecoder` for `PNG` formats and `GifImageDecoder` for `gif` formats. – Mir-Ismaili Dec 14 '18 at 20:11
-
`import sun.awt.image.JPEGImageDecoder` causes this error on Java 9+: `Package 'sun.awt.image' is declared in module 'java.desktop', which does not export it to module 'MODULE_NAME'`! – Mir-Ismaili Dec 15 '18 at 13:54
below code validates .jpeg, .png, .jpg, .tiff images in java
public boolean isValidImage(File f) {
boolean isValid = true;
try {
ImageIO.read(f).flush();
} catch (Exception e) {
isValid = false;
}
return isValid;
}

- 24,677
- 9
- 99
- 108

- 21
- 3
-
In the case of JPG (I haven't tested other formats), this method only works if the content has no header. So it fails to detect incomplete images with header. In that case, `Archimides`'s answer works best as it verifies that the image is complete to the end. – lepe Oct 29 '18 at 06:28
If the image can't be parsed the file is corrupt, otherwise the file should be valid but contains the wrong pixels as Andrzej pointed out. Detecting that might be quite hard if you can't define how you would find "wrong" pixels.
If you have information on the base image, e.g. a histogram or even the original pixels, you might try and compare those with the read image. Note, however, that due to compression there might be some errors, so you'd need to add some tolerance value.
An additional side note: Sanselan won't read JPEG images so you'd have to use ImageIO here.

- 87,414
- 12
- 119
- 157