为啥 UIImage 没有成功解码?

Posted

技术标签:

【中文标题】为啥 UIImage 没有成功解码?【英文标题】:Why doesn't UIImage get successfully decoded?为什么 UIImage 没有成功解码? 【发布时间】:2017-02-08 04:24:49 【问题描述】:

当我尝试使用 NSKeyedArchiver 对其进行编码和解码时,为什么这段代码 sn-p 中的 UIImage 没有恢复到其原始状态?

我希望“decodedImage”包含解码后的图像,但它只是 NULL。

// Any image here seems to repro the issue
UIImage *image = [UIImage imageNamed:@"soda.jpg"];

// This prints YES (1), just a sanity check.
NSLog(@"Confirms %d", [[UIImage class] conformsToProtocol:@protocol(NSCoding)]);

NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

[coder encodeObject:image forKey:@"image"];
[coder finishEncoding];

// I would expect this to be large, instead it's < 1kb.
NSLog(@"Data length is: %zu", (unsigned long)data.length);

NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

// This prints YES (1)
NSLog(@"containsValueForKey returns %d", [decoder containsValueForKey:@"image"]);

// decodedImage is NULL here, even though containsValueForKey returned YES
UIImage *decodedImage = [decoder decodeObjectForKey:@"image"];

[decoder finishDecoding];

在这种情况下,我不是在寻找一种解决方法,比如先将 UIImage 转换为 NSData 并对其进行编码。原因是我试图重现一段不相关的代码,它使用了类似的东西,我试图理解它。

如果我首先通过 nsdata 往返图像并返回到 uiimage,代码会按预期工作,为什么??

UIImage *originalImage = [UIImage imageNamed:@"soda.jpg"];
NSData *imageData = UIImagePNGRepresentation(originalImage);
UIImage *image = [UIImage imageWithData:imageData];

【问题讨论】:

我认为这种怪异与使用 [UIImage imageNamed:] 创建的 UIImage 的序列化方式与其他 UIImage 不同,可能是因为它知道图像来自应用程序捆绑... 【参考方案1】:

检查一下

将数据解码为图像:

+(NSData *)decodeBase64ToImage:(NSString *)strEncodeData


    NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
    return data;


self.btnLicenseFront.image=[UIImage imageWithData:[Themes decodeBase64ToImage:licenseFront]];

【讨论】:

【参考方案2】:

我使用了你的代码并尝试了 2 张图片:

1.正确的图片文件

输出是

> [36133:5889153] Confirms 1 
> [36133:5889153] Data length is: 68267
> [36133:5889153] containsValueForKey returns 1  
> [36133:5889153] decodedImage is 1879681920

2。图片文件不正确/损坏

输出是

> [36130:5888794] Confirms 1 
> [36130:5888794] Data length is: 136
> [36130:5888794] containsValueForKey returns 1 
> [36130:5888794] decodedImage is 0

看来您的源 JPG 文件已损坏或无效。

【讨论】:

我的图像没有损坏,我可以在许多其他应用程序中正常打开它【参考方案3】:

我找到了解决办法。

事实证明,这只发生在图像是通过 [UIImage imageNamed:] 加载的。如果 UIImage 是通过 [UIImage imageWithContentsOfFile:] 创建的,则不会出现此问题。

我相信这一定是ios端的一个bug。 imageNamed: 创建 UIImage 的方式专门用于包内的图像。他们必须进行一些优化,这会导致 NSCoder 无法按预期运行,因为 UIImage 似乎实际上并不包含图像数据(因为解码似乎返回 nil 而不是像预期的那样使用捆绑包中的图像重新创建 UIImage)。

【讨论】:

以上是关于为啥 UIImage 没有成功解码?的主要内容,如果未能解决你的问题,请参考以下文章

由于 EXC_BAD_ACCESS 崩溃,UIImage 没有改变图像,为啥?

无法在iOS swift中将base64string解码为uiimage,但在android中工作正常[重复]

UIImage的线程安全

调整 UIImage 大小的哪种方法更好,为啥?

为啥我的 CGImage 是 UIImage 大小的 3 倍

为啥从相机缩小 UIImage 这么慢?