Как обнаружить поврежденные изображения (PNG, JPG) в Java - PullRequest
11 голосов
/ 07 ноября 2011

Мне нужно определить, не поврежден ли файл изображения в Java. Я работаю только с изображениями PNG, JPG. Можно ли это сделать с Санселаном? Или это можно сделать с помощью ImageIO? Я пытался использовать ImageIO. Кажется, что он работает. Но я не уверен, что он может обнаружить все виды ошибок в изображениях. Я хотел бы знать, что является лучшей практикой.

Ответы [ 4 ]

11 голосов
/ 09 апреля 2012

Вот мое решение, которое будет обрабатывать проверку на наличие битых GIF, JPG и PNG. Он проверяет усеченный JPEG с использованием маркера JPEG EOF, GIF с использованием проверки исключения за пределами индекса и PNG с использованием 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;
    }
 }
}
6 голосов
/ 19 сентября 2012

Если изображение в формате JPEG, используйте это:

JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f));
decoder.produceImage();

если выдает исключение; это означает, что изображение повреждено.

для других случаев; просто используйте new ImageIcon(file), чтобы проверить правильность.

2 голосов
/ 23 августа 2018

код ниже проверяет .jpeg, .png, .jpg, .tiff изображения в java

public boolean isValidImage(File f) {
  boolean isValid = true;
  try {
    ImageIO.read(f).flush();
  } catch (Exception e) {
    isValid = false;
  }
  return isValid;
}
1 голос
/ 07 ноября 2011

Если изображение не может быть проанализировано, файл поврежден, в противном случае файл должен быть действительным, но содержит неправильные пиксели, как указал Анджей.Обнаружить это может быть довольно сложно, если вы не можете определить, как вы найдете «неправильные» пиксели.

Если у вас есть информация о базовом изображении, например, гистограмма или даже исходные пиксели, вы можете попробовать сравнитьте с прочитанным изображением.Однако обратите внимание, что из-за сжатия могут быть некоторые ошибки, поэтому вам нужно будет добавить некоторое значение допуска.

Дополнительное примечание: Sanselan не будет читать изображения JPEG, поэтому вам придется использоватьImageIO здесь.

...