原地址: Norld's Blog -- Core Foundation 學(xué)習(xí) -- 圖片質(zhì)量的壓縮與轉(zhuǎn)換
開始
??在 UIKit 中有兩種圖片質(zhì)量壓縮與轉(zhuǎn)換的寫法:
UIImageJPEGRepresentation(image, 0.75);
UIImagePNGRepresentation(image);
目標(biāo)
??用 Core Foundation
實(shí)現(xiàn)相同功能
流程
-
創(chuàng)建
Translate
類的相關(guān)文件- 包含
Translate.h
和Translate.m
文件 - 刪除所有
@interface
和@implementation
相關(guān)的內(nèi)容- 這一步可不做, 之后的內(nèi)容并沒有操作
Translate
的類或?qū)嵗龑?duì)象
- 這一步可不做, 之后的內(nèi)容并沒有操作
- 包含
-
在
Translate.h
中- 創(chuàng)建結(jié)果相關(guān)的 Blok
typedef void(^complet)(BOOL isSuccess);
- 創(chuàng)建格式轉(zhuǎn)換相關(guān)的枚舉
typedef NS_ENUM(NSUInteger, kUTType) { kUTTypeJPEG, kUTTypePNG };
- 聲明定義壓縮轉(zhuǎn)換方法
extern void TImageRepresentation(NSString *sourceImagePath,NSString *targetImagePatch,double compressionQuality,kUTType type,complet complet);
參數(shù) | 格式 | 定義 |
---|---|---|
sourceImagePath | NSString * |
原圖片文件路徑 |
targetImagePatch | NSString * |
輸出路徑, 必須包含文件名與后綴 |
compressionQuality | double |
圖片壓縮質(zhì)量, 范圍 0~1, 1為最高質(zhì)量 |
type | kUTType |
輸出格式, 務(wù)必與輸出路徑的后綴相同 |
complet | Block |
輸出結(jié)果的回調(diào) |
-
在
Translate.m
中- 引入相關(guān)頭文件
#import <ImageIO/ImageIO.h> #import <UIKit/UIKit.h>
- 開始實(shí)現(xiàn)壓縮轉(zhuǎn)換方法
void TImageRepresentation(NSString *sourceImagePath, NSString *targetImagePatch, double compressionQuality, kUTType type, complet complet) { // do something... }
- 開啟子線程
dispatch_async(dispatch_get_global_queue(0, 0), ^{ // do something... }
- 獲取圖片源數(shù)據(jù)
CGImageRef image = [UIImage imageWithContentsOfFile:sourceImagePath].CGImage;
- 創(chuàng)建接收最終數(shù)據(jù)的目標(biāo)容器
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
- 判斷轉(zhuǎn)換格式
CFStringRef typeStr; switch (type) { case kUTTypeJPEG: typeStr = CFSTR("public.jpeg"); break; case kUTTypePNG: typeStr = CFSTR("public.png"); break; default: break; }
- 創(chuàng)建轉(zhuǎn)換者對(duì)象, 進(jìn)行質(zhì)量壓縮和轉(zhuǎn)換
CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, typeStr, 1, NULL);
CGImageDestinationCreateWithData(_,_,_,_)
函數(shù)的相關(guān)詳情- 創(chuàng)建所需參數(shù)
NSDictionary *properties = @{ (__bridge id)kCGImageDestinationLossyCompressionQuality : @(compressionQuality) };
- 向轉(zhuǎn)換者對(duì)象添加圖片數(shù)據(jù)和參數(shù)數(shù)據(jù)
CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);
CGImageDestinationAddImage(_,_,_)
函數(shù)的相關(guān)詳情- 檢測(cè)轉(zhuǎn)換是否成功, 如失敗直接釋放數(shù)據(jù)源與轉(zhuǎn)換者對(duì)象, 并結(jié)束所有流程
if (!CGImageDestinationFinalize(destination)) { CFRelease(imageData); imageData = NULL; if (complet) { dispatch_async(dispatch_get_main_queue(), ^{ complet(NO); }); } // 釋放轉(zhuǎn)換者對(duì)象 CFRelease(destination); return; }
- 成功后釋放轉(zhuǎn)換者對(duì)象
CFRelease(destination);
- 根據(jù)輸出地址, 創(chuàng)建輸出流
CFAllocatorRef allocator = CFAllocatorGetDefault(); NSURL *fileUrl = [NSURL fileURLWithPath:targetImagePatch]; CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(allocator, (__bridge CFURLRef)fileUrl);
- 開啟輸出流
CFWriteStreamOpen(writeStream);
- 向目標(biāo)容器寫入最終數(shù)據(jù)
CFIndex result = CFWriteStreamWrite(writeStream, CFDataGetBytePtr(imageData), CFDataGetLength(imageData));
CFWriteStreamWrite(_,_,_)
函數(shù)的相關(guān)詳情- 判斷最終數(shù)據(jù)寫入是否成功
??不成功的返回值為 -1, 成功則為輸出的字節(jié)流長(zhǎng)度
if (result != -1) { if (complet) { dispatch_async(dispatch_get_main_queue(), ^{ complet(YES); }); } } else { if (complet) { dispatch_async(dispatch_get_main_queue(), ^{ complet(NO); }); } }
- 關(guān)閉輸出流
CFWriteStreamClose(writeStream);
- 釋放目標(biāo)容器
CFRelease(imageData);
使用
??簡(jiǎn)單使用:
NSString *sourceImagePath = @"要進(jìn)行處理的圖片的路徑";
NSString *targetImagePath = @"處理完成的輸出路徑";
double compressionQuality = 0.75f;
kUTType targetImageType = kUTTypeJPEG;
TImageRepresentation(sourceImagePath, targetImagePath, compressionQuality, targetImageType, ^(BOOL isSuccess) {
if (isSuccess) {
NSLog(@"Winer");
} else {
NSLog(@"Loser");
}
});