Bya*_*ogt 12 java image javax.imageio
我需要检测图像文件是否在Java中被破坏.我只使用PNG,JPG图像.这可能与Sanselan有关吗?或者可以用ImageIO完成吗?我尝试过使用ImageIO.read似乎很有效.但我不确定它是否可以检测到图像中的各种错误.我想知道什么是最好的做法.
Arc*_*ano 12
这是我的解决方案,可以处理损坏的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果是JPEG图像,请使用:
JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f));
decoder.produceImage();
Run Code Online (Sandbox Code Playgroud)
如果它抛出异常; 这意味着图像已损坏.
对于其他情况; 只是new ImageIcon(file)
用来检查有效性.
如果无法解析图像,则文件已损坏,否则文件应该有效,但包含错误的像素,正如 Andrzej 指出的那样。如果您无法定义如何找到“错误”像素,那么检测到这一点可能会非常困难。
如果您有基本图像的信息,例如直方图甚至原始像素,您可以尝试将它们与读取的图像进行比较。但请注意,由于压缩,可能会出现一些错误,因此您需要添加一些容差值。
附加说明:Sanselan 不会读取 JPEG 图像,因此您必须在此处使用 ImageIO。