如何在Java中检测损坏的图像(PNG、JPG)
我需要检测图像文件是否在Java中损坏。我只处理PNG和JPG图像。这可能与梵语有关吗?或者可以用ImageIO完成吗?我试过使用ImageIO.read,看起来很有效。但我不确定它是否能检测出图像中的各种错误。我想知道最佳做法是什么。如果图像无法解析,则文件已损坏,否则文件应有效,但包含错误的像素,正如Andrzej指出的那样。如果无法定义如何找到“错误”像素,那么检测这一点可能相当困难 如果您有关于基础图像的信息,例如直方图或甚至原始像素,您可以尝试将其与读取的图像进行比较。但是,请注意,由于压缩,可能会出现一些错误,因此需要添加一些公差值如何在Java中检测损坏的图像(PNG、JPG),java,image,javax.imageio,Java,Image,Javax.imageio,我需要检测图像文件是否在Java中损坏。我只处理PNG和JPG图像。这可能与梵语有关吗?或者可以用ImageIO完成吗?我试过使用ImageIO.read,看起来很有效。但我不确定它是否能检测出图像中的各种错误。我想知道最佳做法是什么。如果图像无法解析,则文件已损坏,否则文件应有效,但包含错误的像素,正如Andrzej指出的那样。如果无法定义如何找到“错误”像素,那么检测这一点可能相当困难 如果您有关于基础图像的信息,例如直方图或甚至原始像素,您可以尝试将其与读取的图像进行比较。但是,请注意,由
另一个附加说明:Sanselan不会读取JPEG图像,因此您必须在此处使用ImageIO。这是我的解决方案,它可以检查损坏的GIF、JPG和PNG。它使用JPEG EOF标记检查截断的JPEG、使用索引越界异常检查的GIF和使用EOFEException的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;
}
}
}
公共静态图像分析结果分析图像(最终路径文件)
抛出NoSuchAlgorithmException,IOException{
最终ImageAnalysisResult=新ImageAnalysisResult();
final InputStream digestInputStream=Files.newInputStream(文件);
试一试{
最终图像输入流图像输入流=图像IO
.createImageInputStream(digestInputStream);
最终迭代器imageReaders=ImageIO
.getImageReaders(imageInputStream);
如果(!imageReaders.hasNext()){
结果:setImage(假);
返回结果;
}
final ImageReader ImageReader=imageReaders.next();
设置输入(imageInputStream);
最终BuffereImage image=imageReader.read(0);
if(image==null){
返回结果;
}
image.flush();
if(imageReader.getFormatName().equals(“JPEG”)){
imageInputStream.seek(imageInputStream.getStreamPosition()-2);
最终字节[]lastTwoBytes=新字节[2];
imageInputStream.read(最后两个字节);
如果(最后两个字节[0]!=(字节)0xff | |最后两个字节[1]!=(字节)0xd9){
result.setTruncated(true);
}否则{
结果:setTruncated(false);
}
}
结果:setImage(真);
}catch(最终索引AutofBoundsException e){
result.setTruncated(true);
}捕获(最终IIOException e){
if(例如,getCause()实例EOFEException){
result.setTruncated(true);
}
}最后{
digestInputStream.close();
}
返回结果;
}
公共类图像分析结果{
布尔图像;
布尔截断;
public void setImage(布尔图像){
这个图像=图像;
}
公共void集合截断(布尔截断){
this.truncated=截断;
}
}
}
如果图像为JPEG格式,请使用以下方法:
JPEGImageDecoder decoder = new JPEGImageDecoder(new FileImageSource(f) ,new FileInputStream(f));
decoder.produceImage();
如果它抛出异常;这意味着图像已损坏
其他情况,;只需使用
新建图像图标(文件)
检查有效性。下面的代码验证java中的.jpeg、.png、.jpg、.tiff图像
public boolean isValidImage(文件f){
布尔值isValid=true;
试一试{
ImageIO.read(f.flush();
}捕获(例外e){
isValid=false;
}
返回有效;
}
我建议,检测图像中各种错误的唯一方法(其中“错误”定义为导致不完美行为的任何差异)是继续使用图像。图像完全有可能受到损坏,但仍然会生成一个有效的文件,尽管该文件具有“错误的像素”。具体考虑您想要检测的内容可能会很有用。ImageIO可以检测被截断的PNG并引发异常,但对于被截断的JPG,我不能让它抛出异常。你对此有什么解决方案吗?JPEG条件检查的两个子句不应该与logical或而不是AND连接吗?你能链接这个类ImageAnalysisResult吗?你能在你的答案中包含所有导入语句吗?请基于这个答案我建立了一个小库,因为我需要好!希望有帮助:它工作正常,如果它不是有效的jpeg图像,那么它将抛出ImageFormatException。是否有任何方法可以检查mp4文件是否损坏??对PNG
格式使用PNGImageDecoder
,对gif
格式使用GifImageDecoder
。import sun.awt.image.JPEGImageDecoder
在Java 9+上导致此错误:包“sun.awt.image”在模块“Java.desktop”中声明,不会将其导出到模块“module\u NAME”
!对于JPG(我没有测试过其他格式),只有在内容没有标题的情况下,这种方法才有效。因此,它无法检测带有标题的不完整图像。在这种情况下,Archimides
的答案最有效,因为它会验证图像是否完整到底。