首页 > iOS对图像损坏错误:<Error>:ImageIO的处理方法

iOS对图像损坏错误:<Error>:ImageIO的处理方法

在网络不好时,可能请求的图片数据不完整,这时候在imageView展示图片时,因为发现PNG图片不完全正确,所以早console里报错,如下:

<Error>: ImageIO: PNG IDAT: invalid stored block lengths

但这个不是运行时异常,不知道该怎么捕获,从而进行例如重新请求等操作。求解该怎么做?


真是功夫不负有心人,在各种stackoverflow和google无解之后,我自己读了UIImage、UIImageView以及ImageIO的源码和官方说明,找到了个取巧的办法,你需要写下面两步代码:

1.读取图片数据,然后调用2中的方法进行校验

NSData* data = [NSData dataWithContentsOfFile:imagePath];

2.判断是否为有效的PNG图片,JPG的请使用UIImageJPEGRepresentation方法

/**
 *  校验图片是否为有效的PNG图片
 *
 *  @param imageData 图片文件直接得到的NSData对象
 *
 *  @return 是否为有效的PNG图片
 */
- (BOOL)isValidPNGByImageData:(NSData*)imageData
{
    UIImage* image = [UIImage imageWithData:imageData];
    //第一种情况:通过[UIImage imageWithData:data];直接生成图片时,如果image为nil,那么imageData一定是无效的
    if (image == nil && imageData != nil) {

        return NO;
    }

    //第二种情况:图片有部分是OK的,但是有部分坏掉了,它将通过第一步校验,那么就要用下面这个方法了。将图片转换成PNG的数据,如果PNG数据能正确生成,那么这个图片就是完整OK的,如果不能,那么说明图片有损坏
    NSData* tempData = UIImagePNGRepresentation(image);
    if (tempData == nil) {
        return NO;
    } else {
        return YES;
    }
}

真是眼泪都留下来了!~


图片能正常显示么?

如果不能正常显示的话,你可以自己先做一个验证操作,如果自己验证过了再赋值给imageView,这种错误也不该无视吧?毕竟图片确实有问题。

如果你实在想让它不显示,我觉得有三条个办法:

  1. Method Swizzling 替换掉打日志的那个方法
  2. 日志重定向
  3. 检测是不是只有在定义 DEBUG 宏的时候才输出,如果是的话就好办了,在设置的时候取消宏,然后再给加上

so上找到的检测 PNG 的方法:

- (BOOL)dataIsValidPNG:(NSData *)data
{
    if (!data || data.length < 12)
    {
        return NO;
    }

    NSInteger totalBytes = data.length;
    const char *bytes = (const char *)[data bytes];

    return (bytes[0] == (char)0x89 && // PNG
            bytes[1] == (char)0x50 &&
            bytes[2] == (char)0x4e &&
            bytes[3] == (char)0x47 &&
            bytes[4] == (char)0x0d &&
            bytes[5] == (char)0x0a &&
            bytes[6] == (char)0x1a &&
            bytes[7] == (char)0x0a &&

            bytes[totalBytes - 12] == (char)0x00 && // IEND
            bytes[totalBytes - 11] == (char)0x00 &&
            bytes[totalBytes - 10] == (char)0x00 &&
            bytes[totalBytes - 9] == (char)0x00 &&
            bytes[totalBytes - 8] == (char)0x49 &&
            bytes[totalBytes - 7] == (char)0x45 &&
            bytes[totalBytes - 6] == (char)0x4e &&
            bytes[totalBytes - 5] == (char)0x44 &&
            bytes[totalBytes - 4] == (char)0xae &&
            bytes[totalBytes - 3] == (char)0x42 &&
            bytes[totalBytes - 2] == (char)0x60 &&
            bytes[totalBytes - 1] == (char)0x82);
}

Objective-C的hook方案(一): Method Swizzling
IOS应用发布NSLog的注释及使用重定向,把控制台内容写入文件
PNG validation on iOS

【热门文章】
【热门文章】