参考: 谈谈 iOS 中图片的解压缩
#####imageNamed:加载bundle图片 通过 imageNamed 创建 UIImage 时,系统实际上只是在 Bundle 内查找到文件名,然后把这个文件名放到 UIImage 里返回,并没有进行实际的文件读取和解码。当 UIImage 第一次显示到屏幕上时,其内部的解码方法才会被调用,同时解码结果会保存到一个全局缓存去。
+ (nullable UIImage *)imageNamed:(NSString *)name; // load from main bundle
复制代码
UIImage *image = [UIImage imageNamed:@"XXX.png"];
复制代码
缓存:首先去系统缓存中查找是否有图片,找到返回;找不到则从bundle中加载图片并返回,同时将图片缓存到系统中。缓存的图片只有在收到内存警告时才会释放。
线程安全性:iOS 9.0之前不是线程安全的,iOS 9.0之后Apple作了优化处理,将其改为线程安全的方法。
#####通过路径加载图片
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"logo" ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
// 但是在开发中,笔者通常会定义成宏,简化调用
#define kResourcePath(name, type) ([[NSBundle mainBundle] pathForResource:name ofType:type])
#define kImgFromFile(name, type) [UIImage imageWithContentsOfFile:kResourcePath(name, type)]
// 然后,调用也变得很简化了~
UIImage *image = kImgFromFile(@"logo", @"png");
复制代码
#####NSDate转成UIImage,scale缩放参数
+ (nullable UIImage *)imageWithData:(NSData *)data;
+ (nullable UIImage *)imageWithData:(NSData *)data scale:(CGFloat)scale NS_AVAILABLE_IOS(6_0);
- (nullable instancetype)initWithData:(NSData *)data;
- (nullable instancetype)initWithData:(NSData *)data scale:(CGFloat)scale NS_AVAILABLE_IOS(6_0);
复制代码
// 以为是放大十倍,结果是缩小了十倍。但是image.cgImage大小不变
UIImage *image = [UIImage imageWithData:data scale:10]; // po image.size: (width = 64, height = 38.6)
UIImage *image = [UIImage imageWithData:data scale:1]; // po image.size: (width = 640, height = 386)
复制代码
#####UIImage转成NSData
UIImage *image = [UIImage imageWithData: imageData];
// 方法1
NSData *imageData = UIImagePNGRepresentation(image);
// 方法2
NSData *imageData = UIImageJPEGRepresentation(image,1);// 0到1
复制代码
#####拉伸、平铺图片,指定UIEdgeInsets区域
typedef NS_ENUM(NSInteger, UIImageResizingMode) {
UIImageResizingModeTile,// 平铺模式
UIImageResizingModeStretch,// 拉伸模式
};
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(5_0);
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode NS_AVAILABLE_IOS(6_0);
@property(nonatomic,readonly) UIEdgeInsets capInsets NS_AVAILABLE_IOS(5_0); // default is UIEdgeInsetsZero for non resizable images
@property(nonatomic,readonly) UIImageResizingMode resizingMode NS_AVAILABLE_IOS(6_0); // default is UIImageResizingModeTile
// 定义可拉伸的图片
#define kResizableImage(name,top,left,bottom,right) [[UIImage imageNamed:name] resizableImageWithCapInsets:UIEdgeInsetsMake(top,left,bottom,right)]
复制代码
#####CGImage和UIImage相互转换
// UIImage ->CGimageRef
UIImage *image = [UIImage imageNamed:@"xxx.png"];
CGImageRef ciRef = [image CGImage];
// CGImage ->UIImage
CGImageRef ciRef ...
UIImage *image = [UIImage imageWithCGImage:ciRef];
复制代码
#####保存图片到相册
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);//保存图片到照片库(PNG格式)
复制代码
[ALAssetsLibrary writeImageDataToSavedPhotosAlbum:metadata:completionBlock] 可以直接把 APNG、GIF 的数据写入相册
// 从相册获取图片时,直接去读 data 二进制数据,就能原封不动的取出来。
复制代码
####UIImage保存到磁盘,用什么方式最好? 保存 UIImage 有三种方式: 1.直接用 NSKeyedArchiver 把 UIImage 序列化保存(内部是UIImagePNGRepresentation)(消耗最大), 2.用 UIImagePNGRepresentation() 先把图片转为 PNG 保存, 3.用 UIImageJPEGRepresentation() 把图片压缩成 JPEG 保存(图片不包含透明像素时,最佳)。