如何检测jpg jpeg图像文件是否已损坏(不完整)?

时间:2017-10-18 04:31:51

标签: image image-processing web jpeg

我必须在我的网站上显示来自其他人的图像服务器的一些图像,但是图像服务器中的一些图像只能部分显示如下图像 enter image description here

图像包含宽度和高度信息,但仅显示图像的顶部。如果我使用Chrome v61打开图片,它看起来就像下面的图片 enter image description here

Chrome v61会显示此颜色以显示png图像文件中的透明度,但它在jpg jpeg图像文件中的含义是什么?

有没有人知道如何检测这种损坏的(不完整的)图像?我试图避免在我的网站上显示这种图像。

2 个答案:

答案 0 :(得分:6)

我使用 ImageMagick 创建了一个JPEG来测试它,如下所示:

convert -size 1024x768 gradient: image.jpg

它是14kB。你的图像看起来不完整,所以我在3kB之后切断了所有内容:

dd if=image.jpg bs=3000 count=1 > corrupt.jpg

现在,如果我运行 ImageMagick identify命令并放弃stdout,只需保留stderr,我就会:

identify -verbose corrupt.jpg > /dev/null

示例输出

identify: Premature end of JPEG file `corrupt.jpg' @ warning/jpeg.c/JPEGWarningHandler/364.
identify: Corrupt JPEG data: premature end of data segment `corrupt.jpg' @ warning/jpeg.c/JPEGWarningHandler/364.

或者,您也可以放弃stderr,只需查看退出代码(0 =成功,其他任何内容=错误):

identify -regard-warnings -verbose corrupt.jpg > /dev/null 2>&1
echo $?
1

而对于完整的图像:

identify -regard-warnings -verbose image.jpg > /dev/null 2>&1
echo $?
0

ImageMagick 安装在大多数Linux发行版上,可用于macOS / OSX和Windows。

答案 1 :(得分:2)

如果您需要“编程”方法而不是@MarkSetchell建议的命令行方法,您可以在几乎任何编程语言中为此创建一个非常快速的测试。 请注意,这只会找到您在问题中提到的截断损坏类型。 Mark的方法对于查找一般的损坏可能更为可靠。

众所周知,任何JPEG文件或流都是根据JPEG Interchange Format编写的。这意味着它们必须以SOI(图像开始)标记(两个字节0xFF, 0xD8)开头,并以EOI(图像结束)标记结束(两个字节,0xFF, 0xD9) 。在JPEG文件/流中的任何其他地方都找不到这两个标记。

如果您首先通过检查前两个字节并将其与SOI标记匹配来将文件识别为JPEG,则可以跳到最后并向后搜索EOI标记。最有可能的是,这将是最后两个字节,或者根本不会找到它们。但是进行搜索可能更安全(可能是有限的长度),因为我认为可以允许在EOI之后将特定于应用程序的数据放在JPEG文件中(如果我错了,请纠正我)。