Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect corrupted images (PNG, JPG) in Java

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.

like image 645
Byambatsogt Avatar asked Nov 07 '11 16:11

Byambatsogt


People also ask

Can Java read PNG?

Java 2D supports loading these external image formats into its BufferedImage format using its Image I/O API which is in the javax. imageio package. Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP.

How do you check if the file is corrupted in C#?

The best way to determine that the file is corrupted is to use specialized libraries of that type like PDF file libraries. There are lots of both free and commercial of such libraries for . NET. You may simply try to load file with one of such libraries.


1 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;
    }
 }
}
like image 72
Archimedes Trajano Avatar answered Sep 19 '22 06:09

Archimedes Trajano