我需要检测图像文件是否在Java中被破坏。我只使用PNG,JPG图像。这可能与Sanselan有关吗?或者可以用ImageIO完成吗?我尝试过使用ImageIO.read似乎很有效。但我不确定它是否可以检测到图像中的各种错误。我想知道什么是最好的做法。
答案 0 :(得分:11)
这是我的解决方案,可以处理损坏的GIF,JPG和PNG。它使用JPEG EOF标记检查截断的JPEG,使用索引超出边界的异常检查检查GIF,使用EOFException检查PNG
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;
}
}
}
答案 1 :(得分:6)
如果是JPEG图像,请使用:
JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f));
decoder.produceImage();
如果它抛出异常;这意味着图像已损坏。
其他案件;只需使用new ImageIcon(file)
来检查有效性。
答案 2 :(得分:2)
以下代码在Java中验证.jpeg,.png,.jpg,.tiff图像
public boolean isValidImage(File f) {
boolean isValid = true;
try {
ImageIO.read(f).flush();
} catch (Exception e) {
isValid = false;
}
return isValid;
}
答案 3 :(得分:1)
如果无法解析图像,则文件已损坏,否则文件应该有效但包含错误的像素,正如Andrzej所指出的那样。如果您无法定义如何找到“错误”的像素,则检测到这可能会非常困难。
如果您有关于基本影像的信息,例如直方图甚至是原始像素,您可以尝试将它们与读取的图像进行比较。但请注意,由于压缩可能会出现一些错误,因此您需要添加一些容差值。
另外注意:Sanselan不会读取JPEG图像,因此您必须在此处使用ImageIO。