如何在 iPhone 上检查图片是否有效

3

如何检查图片是否有效

例如,当我缓存一个仅下载了一半并失败的图像,且此图像为无效图像时,我想知道它是无效图像并重新下载。 (当我使用损坏的图像时,Xcode控制台会记录错误:ImageIO: PNG IDAT: CRC error

因此,我想找到一种机制来检查各种JPEG、PNG等图像的有效性

有人有线索吗?


这是一个类似的编程问题:https://dev59.com/8UjSa4cB1Zd3GeqPEVJ0。请返回仅翻译的文本内容。 - Maulik
4个回答

5
我会从检查有效的标题开始。 其次是页脚。通常,最后8个字节的无符号整数值顺序应为“73,69,78,68,174,66,96,130”。 这些数据转换为Int64等于5279712195050102914。 对于png,这应该是正确的 :)

if (memcmp(img_bytes, "\211PNG", 4) != 0||OSReadBigInt64(img_bytes,(length - 8))!=5279712195050102914)

{

  //Bad Data! Free your data and return or something

}


1
Begeesy的答案应该足够了。一个更完整的解决方案是检查前8个字节而不仅仅是限制在前4个字节。"\211PNG\r\n\032\n"。请参阅http://www.fileformat.info/format/png/spec/4b57267b1c1941cf8794fdc952287a26/view.htm中的PNG签名文件部分。 - Bill

1
这是因为您正在使用相同的类从服务器下载图像文件,并请求连续下载相同的文件,而它已经在下载该文件,这导致先前的文件下载失败并导致部分下载的文件。

0
我建议您获取图像的文件大小并将其与刚下载的图像文件进行比较。

这是一种简单的方法,但我想要检查图片本身。 - aelam
1
你的意思是要在Objective-C中进行CRC计算吗?之前有人尝试过: http://stackoverflow.com/questions/6974961/why-does-crc-return-different-value-when-inside-objective-c-method-instead-of-st - Raptor

0
从网络加载图像有两种明显的失败情况:
  1. 下载的文件根本不是图像。
  2. 下载的数据仅包含图像数据的一部分。
对于第一种情况,用nil检查各种UIImage方法的返回值可能是处理此错误情况的最佳方法。 以下是UIImage上的类方法,如果未能使用提供的数据初始化图像,则会返回nil:+ (UIImage *)imageWithData:(NSData *)data+ (UIImage *)imageWithContentsOfFile:(NSString *)path。 执行nil检查的代码可能如下所示:
UIImage *image = [UIImage imageWithContentsOfFile:pathToImage];
if (image) {
    // The image was loaded. Display it
}
else {
    // The image was not loaded. Redownload or display a placeholder, etc...
}

对于第二种失败情况,很可能是由于连接丢失导致的。对于这种情况,最好在 NSURLConnection 的代理中处理失败。当下载图像时,如果调用了 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error,则应该丢弃请求的数据。

还要记住,didFailWithError: 不会针对服务器返回的 4xx 或 5xx 响应而被调用。它是在连接因其他原因被切断时被调用的。通常最好确保只有在服务器响应 200 OK 时才将图像数据写入磁盘。


4
不可以。如果图像的头部正确,它可以被初始化为UIImage然后显示一半。 - aelam
我已经更新了如何处理两种常见故障情况的答案。仅检查图像本身很困难,因为您必须单独处理所有不同的格式。这很困难、烦人且通常不值得。 - Evan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接