PowerShell脚本检索从手机发送的入站邮件,并将jpeg文件附件存储在数据库中。不幸的是,邮件消息通常是从服务质量较差的区域发送的,邮件消息会被截断,通常是中间附件。即使邮件消息已被截断,邮件服务器仍然接受它们。正如在Stack Overflow和其他地方的一些帖子中所描述的,检查附件是否完整的一种可能方法是查找标记jpeg文件末尾的FF D9字节:
$binaryReader = New-Object BinaryReader([File]::Open($filePath, [FileMode]::Open))
$binaryReader.BaseStream.Seek(-2, [SeekOrigin]::End)
[byte[]]$bytes = New-Object byte[] 2
$binaryReader.Read($bytes, 0, 2)
if (($bytes[0] -eq 0xFF) -and ($bytes[1] -eq 0xD9)) {
不幸的是,对于某些移动运营商或可能是移动运营商和手机操作系统的组合,jpeg图像似乎附加了额外的字节。生成的jpeg图像不会被截断,可以在ImageMagick中加载并使用标准图形查看器查看,但上述测试将失败。许多jpeg附件以一个以下面八个字节序列结尾的可变blob数据结束:0x57 0x40 0x40 0x43 0x72 0x65 0x65 0x66但是还有其他变化。
我想到,如果jpeg标题指定图像的高度和宽度,则可能有不同的方法来测试截断。代码可以加载图像并尝试读取右下角的像素,看看是否有错误。
$bitmap = [System.Drawing.Bitmap]::FromFile($filePath)
$pixelColor = $bitmap.GetPixel($bitmap.Width - 1, $bitmap.Height - 1)
我抓住了一个严重截断的jpeg文件 - 一个文件大小较小的文件,当在图像查看器中显示时,照片顶部有一个矩形条,可见,但其余部分是空白的。对文件运行上面的代码时,Bitmap对象的宽度和高度为2560 x 1536,这是非trucated文件的典型尺寸。我希望GetPixel调用以检索最后一个像素的颜色将返回null或抛出异常但它没有。它返回了一个RGB值,就像文件没有被截断一样。
我在PowerShell 4和Windows Server 2012上的.NET Framework 4下运行此代码。我想也许在实例化位图对象时,.NET已经分配了一个足够大的内存缓冲区来保存基于维度的位图jpeg标头,然后加载尽可能多的数据。但是,当我在右下角附近采样各种像素时,颜色对象有数据。这是位置x = 2559,y = 1535的颜色值:R:114,G:113,B:111。
当没有数据可用时,这看起来不是默认的灰色,因为其他相邻像素具有不同的值。对于我在白色区域看到的小像素样本的RGB值值得看的值,往往在110到116的范围内。相比之下,顶部的RGB值有很多变化。左角。
为什么这种方法不起作用?当提供截断的文件时,为什么.NET Framework Bitmap对象不会抛出错误?幻像素颜色值是否来自未初始化的内存?还有什么我应该尝试提出可靠的截断测试吗?
答案 0 :(得分:0)
ImageMagick将检测截断的JPEG文件。例如:
$ convert -regard-warnings truncated.jpg x.png
convert: Premature end of JPEG file `truncated.jpg' @ warning/jpeg.c/JPEGWarningHandler/352.
convert: Corrupt JPEG data: premature end of data segment `truncated.jpg' @ warning/jpeg.c/JPEGWarningHandler/352.
$ echo $?
1
-regard-warnings
标志使convert
在警告时返回非零退出代码。
或者,IJG JPEG decoder将对截断的文件发出警告。如果你准备写一些C,你可以在你的图像上运行它。
过程如下:
将解压缩程序指向您的文件。
重复获取扫描线,直到您看到整个图像。
检查错误管理器中的num_warnings
字段。如果它> 0,则表示您遇到了问题。
分发中的example.c
非常有用。还有libjpeg-turbo,它与IJG解码器ABI兼容,如果速度有问题,速度要快得多。
答案 1 :(得分:0)
实际上,很容易判断图像是否被截断:没有EOI市场。同样,如果在EOS市场之后有数据,则会增加额外的数据。
JPEG解压缩过程将始终使用SOF标记中的图像大小来解码扫描。