1.保存Gif到相册
iOS的相册是支持保存Gif和APNG动图的,只是不能直接播放。用[ALAssetsLibrary writeImageDataToSavedPhotosAlbum:metadata:completionBlock]可以直接把APNG/GIF的数据写入相册。如果想省事直接用UIImageWriteToSavedPhotosAlbum()写相册,那么图像会被强制转成PNG.
2.把UIImage保存到磁盘的三种方式
1)、直接用NSKeyedArchiver把UIImage序列化保存。
2)、用UIImagePNGRepresentation()把图片转为PNG保存。
3)、用UIImageJPEGRepresentation()把图片压缩成JPEG保存。
比较:NSKeyedArchiver是调用了UIImagePNGRepresentation进行序列化的,用它来保存图片是消耗最大的。苹果对JPEG有硬编码和硬解码,保存成JPEG会大大缩减编解码的时间,也能减小文件体积。所以如果不包含透明像素时,UIImageJPEGRepresentation(0.9)是最佳的图片保存方式。其次是UIImagePNGRepresentation()。
3.UIImage缓存
通过imageNamed创建UIImage时,系统实际上只是在Bundle内查找到文件名,然后把这个文件名放到UIImage时返回,并没有进行实际的文件读取和解码。当UIImage第一次显示到屏幕上时,其内部的解码方法才会被调用,同时解码结果会保存到一个全局缓存去。据我观察,在图片解码后,App第一次退到后台和收到内存警告时,该图片的缓存才会被清空,其他情况下缓存会一直存在。那要是用imageWithData能不能避免缓存呢?
答案是不能,通过数据创建UIImage时,UIImage底层是调用ImageIO的CGImageSourceCreateWithData()方法。该方法有个参数叫ShouldCache,在64位的设备上,这个参数是默认开启的。这个图片也是同样在第一次显示到屏幕时才会被解码,随后解码数据被缓存到CGImage内部 。与imageNamed创建的图片不同,如果这个图片被释放掉,其内部的解码数据也会被立刻释放。那么如果判断一个文件的图片类型?
通过读取文件或数据的头几个字节然后和对应图片格式标准进行比对。这里有一个用SDWebImage判断方法:
[Objective-C] 纯文本查看 复制代码 uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return SDImageFormatJPEG;
case 0x89:
return SDImageFormatPNG;
case 0x47:
return SDImageFormatGIF;
case 0x49:
case 0x4D:
return SDImageFormatTIFF;
case 0x52: {
if (data.length >= 12) {
//RIFF....WEBP
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
return SDImageFormatWebP;
}
}
break;
}
case 0x00: {
if (data.length >= 12) {
//....ftypheic ....ftypheix ....ftyphevc ....ftyphevx
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding];
if ([testString isEqualToString:@"ftypheic"]
|| [testString isEqualToString:@"ftypheix"]
|| [testString isEqualToString:@"ftyphevc"]
|| [testString isEqualToString:@"ftyphevx"]) {
return SDImageFormatHEIC;
}
}
break;
}
}
|