我必须在我的网站上显示来自其他人的图像服务器的一些图像,但是图像服务器中的一些图像只能部分显示如下图像
图像包含宽度和高度信息,但仅显示图像的顶部。如果我使用Chrome v61打开图片,它看起来就像下面的图片
Chrome v61会显示此颜色以显示png图像文件中的透明度,但它在jpg jpeg图像文件中的含义是什么?
有没有人知道如何检测这种损坏的(不完整的)图像?我试图避免在我的网站上显示这种图像。
答案 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文件中(如果我错了,请纠正我)。