參考: 談談 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 儲存(圖片不包含透明畫素時,最佳)。