Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中检测损坏的图像(PNG、JPG)_Java_Image_Javax.imageio - Fatal编程技术网

如何在Java中检测损坏的图像(PNG、JPG)

如何在Java中检测损坏的图像(PNG、JPG),java,image,javax.imageio,Java,Image,Javax.imageio,我需要检测图像文件是否在Java中损坏。我只处理PNG和JPG图像。这可能与梵语有关吗?或者可以用ImageIO完成吗?我试过使用ImageIO.read,看起来很有效。但我不确定它是否能检测出图像中的各种错误。我想知道最佳做法是什么。如果图像无法解析,则文件已损坏,否则文件应有效,但包含错误的像素,正如Andrzej指出的那样。如果无法定义如何找到“错误”像素,那么检测这一点可能相当困难 如果您有关于基础图像的信息,例如直方图或甚至原始像素,您可以尝试将其与读取的图像进行比较。但是,请注意,由

我需要检测图像文件是否在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
的答案最有效,因为它会验证图像是否完整到底。