检查Java中损坏的JPEG文件

时间:2015-04-13 15:54:17

标签: java jpeg

我需要一种快速的Java方法来检查JPEG文件是否有效,或者它是否是截断/损坏的图像。

我尝试过以下两种方式:

  • 使用javax.ImageIO库

    public boolean check(File image) throws IOException {
        try {
            BufferedImage bi = ImageIO.read(image);
            bi.flush();
        } catch (IIOException e) {
            return false;
        }
        return true;
    }
    

    但是它只能检测出我测试过的文件中几个已损坏的文件,并且速度非常慢(在我的电脑上大约每1张图像一次)。

  • Apache Commons Imaging

    public boolean check(File image) throws IOException {
        JpegImageParser parser = new JpegImageParser();
        ByteSourceFile bs = new ByteSourceFile(image);
        try {
            BufferedImage bi = parser.getBufferedImage(bs, null);
            bi.flush();
    
            return true;
        } catch (ImageReadException e) {
            return false;
        }
    }
    

    此代码可以检测到我测试过的所有损坏的图像,但性能非常差(在我的电脑上小于1张图像/秒)。

我正在寻找UNIX程序 jpeginfo 的Java替代品,大约快10倍(在我的电脑上大约10张图像/秒)

4 个答案:

答案 0 :(得分:3)

我查看了JPEG format,根据我的理解,最后EOI(图像结束)两个字节(FF D9)的段应该是最后一个。

boolean jpegEnded(String path) throws IOException {
    try (RandomAccessFile fh = new RandomAccessFile(path, "r")) {
        long length = fh.length();
        if (length < 10L) { // Or whatever
            return false;
        }
        fh.seek(length - 2);
        byte[] eoi = new byte[2];
        fh.readFully(eoi);
        return eoi[0] == -1 && eoi[1] == -23; // DD D9
    }
}

答案 1 :(得分:2)

可能不是最好的答案,但是......

你提到的jpeginfo程序是在C语言中。这让我回想起当时我想在我正在开发的Java应用程序中使用由海军编写的代码(在C ++中)。

我有两个选择:

  1. 使用JNI(Java Native Interface)将我的java代码链接到C ++(在您的案例中为C)库。
  2. 将C ++库翻译成java代码。
  3. 选项1对我来说很难,因为我需要将一个对象传递给库并从库中取回对象(S),这迫使我做选项2(另外,由于截止日期调度)。

    所以在你的情况下,因为我不知道Java中任何其他符合你要求的库,我会建议这两个选项,或者可能构建你自己的解析器。

答案 2 :(得分:1)

判断JPEG图像是否已损坏的唯一方法是解压缩它。

你问是否有快捷方式。你可以肯定地将速度换成准确性。最简单的方法是检查流是否在前面有一个SOI标记,在末尾有一个EOI标记。

接下来,您可以尝试解析标记以确保它们具有有效值。

答案 3 :(得分:0)

这不是本机Java方法,但您总是可以使用jpeginfo或imagemagick's identify等程序 - shell的开销可能比Java库花费的时间少。

我必须做类似的事情,我发现我可以使用Runtime.exec从一个字节数组中调用identify -regard-warnings -verbose - stdin,在2013 macbook pro上大约200ms(我正在检查mp3艺术品,因此图像大小约为300x300px)。不是很好,但速度超过每秒1张图像!

(注意我的图片我必须为imagemagick指定-verbose以获取一些错误)