Core Foundation 學(xué)習(xí) -- 圖片質(zhì)量的壓縮與轉(zhuǎn)換

原地址: 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.hTranslate.m 文件
    • 刪除所有 @interface@implementation 相關(guān)的內(nèi)容
      • 這一步可不做, 之后的內(nèi)容并沒有操作 Translate 的類或?qū)嵗龑?duì)象
  • 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");
    }
});

相關(guān)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盒至,一起剝皮案震驚了整個(gè)濱河市胰蝠,隨后出現(xiàn)的幾起案子澎剥,更是在濱河造成了極大的恐慌煞烫,老刑警劉巖扇救,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異氧猬,居然都是意外死亡壁涎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門山林,熙熙樓的掌柜王于貴愁眉苦臉地迎上來房待,“玉大人,你說我怎么就攤上這事驼抹∩:ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵框冀,是天一觀的道長(zhǎng)流椒。 經(jīng)常有香客問我,道長(zhǎng)明也,這世上最難降的妖魔是什么宣虾? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任惯裕,我火速辦了婚禮,結(jié)果婚禮上绣硝,老公的妹妹穿的比我還像新娘蜻势。我一直安慰自己,他們只是感情好鹉胖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布握玛。 她就那樣靜靜地躺著,像睡著了一般甫菠。 火紅的嫁衣襯著肌膚如雪挠铲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天寂诱,我揣著相機(jī)與錄音拂苹,去河邊找鬼。 笑死痰洒,一個(gè)胖子當(dāng)著我的面吹牛醋寝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播带迟,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼囱桨!你這毒婦竟也來了仓犬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤舍肠,失蹤者是張志新(化名)和其女友劉穎搀继,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翠语,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叽躯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肌括。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片点骑。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谍夭,靈堂內(nèi)的尸體忽然破棺而出黑滴,到底是詐尸還是另有隱情,我是刑警寧澤紧索,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布袁辈,位于F島的核電站,受9級(jí)特大地震影響珠漂,放射性物質(zhì)發(fā)生泄漏晚缩。R本人自食惡果不足惜尾膊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荞彼。 院中可真熱鬧冈敛,春花似錦、人聲如沸卿泽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)签夭。三九已至齐邦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間第租,已是汗流浹背措拇。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慎宾,地道東北人丐吓。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像趟据,于是被迫代替她去往敵國(guó)和親券犁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容