UIImage的分類:截圖功能和修改圖片中的指定顏色

一,截圖一般需要用到兩大功能:全屏截圖和指定區(qū)域截圖桃移。
二屋匕,拿到一些圖片,需要對(duì)圖片進(jìn)行合成的時(shí)候借杰,外層圖片的底色會(huì)很討厭过吻,我們需要把那層討厭的顏色去掉,換成透明的蔗衡,或者指定的某種顏色纤虽。比如我們代碼生成的二維碼圖片,默認(rèn)出來(lái)就是白色底绞惦,但是將該二維碼和展示公司形象的圖片組合的時(shí)候逼纸,那張白色底在很顯眼,最好是給換成透明的济蝉。

全屏截圖需要考慮的是當(dāng)前界面是否有導(dǎo)航欄杰刽,指定區(qū)域截圖需要考慮的是當(dāng)前手機(jī)屏幕對(duì)圖片的縮放比例。
修改圖片的顏色王滤,其實(shí)是遍歷該image的每個(gè)像素點(diǎn)贺嫂,然后找到對(duì)應(yīng)的ARGB進(jìn)行值替換。

/**
 *  將圖片中的指定顏色轉(zhuǎn)換為透明
 */
- (UIImage *)imageToTransparentWithOriginalColor:(UIColor *)originalColor {
    // 分解原來(lái)的顏色
    CGFloat red = 0.0;
    CGFloat green = 0.0;
    CGFloat blue = 0.0;
    CGFloat alpha = 0.0;
    [originalColor getRed:&red green:&green blue:&blue alpha:&alpha];
    
    // 分配內(nèi)存
    const int imageWidth = self.size.width;
    const int imageHeight = self.size.height;
    size_t bytesPerRow = imageWidth * 4;
    uint32_t *rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);
    
    // 創(chuàng)建context
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), self.CGImage);
    
    // 遍歷像素
    int pixelNum = imageWidth * imageHeight;
    uint32_t* pCurPtr = rgbImageBuf;
    for (int i = 0; i < pixelNum; i++, pCurPtr++) {
        //將像素點(diǎn)轉(zhuǎn)成子節(jié)數(shù)組來(lái)表示---第一個(gè)表示透明度即ARGB這種表示方式雁乡。ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
        //分別取出RGB值后第喳。進(jìn)行判斷需不需要設(shè)成透明。
        uint8_t* ptr = (uint8_t *)pCurPtr;
        // NSLog(@"1是%d,2是%d,3是%d",ptr[1],ptr[2],ptr[3]);
        if(ptr[1] == red * 255 || ptr[2] == green * 255 || ptr[3] == blue * 255) {
            ptr[0] = 0;
        }
    }
    
    // 將內(nèi)存轉(zhuǎn)成image
    CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider, NULL, true,kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
    
    // 釋放
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    return resultUIImage;
}
/**
 *  將圖片中的指定顏色轉(zhuǎn)換為新的顏色
 *
 *  @pram originalColor 原來(lái)的顏色
 *  @pram newColor      新的顏色
 */
- (UIImage *)imageOriginalColor:(UIColor *)originalColor toNewColor:(UIColor *)newColor {
    // 分解原來(lái)的顏色
    CGFloat red1 = 0.0;
    CGFloat green1 = 0.0;
    CGFloat blue1 = 0.0;
    CGFloat alpha1 = 0.0;
    CGFloat red2 = 0.0;
    CGFloat green2 = 0.0;
    CGFloat blue2 = 0.0;
    CGFloat alpha2 = 0.0;
    [originalColor getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
    [newColor getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];
    
    // 分配內(nèi)存
    const int imageWidth = self.size.width;
    const int imageHeight = self.size.height;
    size_t bytesPerRow = imageWidth * 4;
    uint32_t *rgbImageBuf = (uint32_t *)malloc(bytesPerRow * imageHeight);
    
    // 創(chuàng)建context
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), self.CGImage);
    
    // 遍歷像素
    int pixelNum = imageWidth * imageHeight;
    uint32_t* pCurPtr = rgbImageBuf;
    for (int i = 0; i < pixelNum; i++, pCurPtr++) {
        // 將像素點(diǎn)轉(zhuǎn)成子節(jié)數(shù)組來(lái)表示---第一個(gè)表示透明度即ARGB這種表示方式蔗怠。
        // ptr[0]:透明度,ptr[1]:R,ptr[2]:G,ptr[3]:B
        uint8_t* ptr = (uint8_t *)pCurPtr;
        if (ptr[0] == alpha1) ptr[0] = alpha2;
        if (ptr[1] == red1 * 255) ptr[1] = red2 * 255;
        if (ptr[2] == green1 * 255) ptr[2] = green2 * 255;
        if (ptr[3] == blue1 * 255) ptr[3] = blue2 * 255;
    }
    
    // 將內(nèi)存轉(zhuǎn)成image
    CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace, kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider, NULL, true,kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
    
    // 釋放
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    
    return resultUIImage;
}
/**
 *  全屏截圖
 */
+ (UIImage *)screenShot {
    return  [self screenShotWithRect:[UIApplication sharedApplication].keyWindow.bounds isNavigation:NO];
}
/**
 *  屏幕截圖
 *
 *  @pram rect         截圖的frame
 *  @pram isNavigation 導(dǎo)航欄是否顯示
 */
+ (UIImage *)screenShotWithRect:(CGRect)rect isNavigation:(BOOL)isNavigation {
    // 獲取屏幕放大比例
    CGFloat scale = [UIScreen mainScreen].scale;
    CGRect newRect = rect;
    newRect.size.width *= scale;
    newRect.size.height *= scale;
    CGFloat height = 0;
    if (isNavigation) {
        height = NavigationViewHeight;
    }
    newRect.origin.y += height;
    newRect.origin.x *= scale;
    newRect.origin.y *= scale;
    // 設(shè)置截屏大小
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(newRect.size.width, newRect.size.height), YES, 0);
    [[UIApplication sharedApplication].keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGImageRef imageRef = viewImage.CGImage;
    // 設(shè)置截圖的區(qū)域
    CGImageRef imageRefRect = CGImageCreateWithImageInRect(imageRef, newRect);
    UIImage *sendImage = [[UIImage alloc] initWithCGImage:imageRefRect];
    // 保存圖片到照片庫(kù)
    //    UIImageWriteToSavedPhotosAlbum(sendImage, nil, nil, nil);
    return sendImage;
}
/**
 *  返回截取到的圖片數(shù)據(jù)類型
 */
+ (NSData *)dataWithScreenshot {
    UIImage *image = [self imageWithScreenshot];
    UIGraphicsEndImageContext();
    return UIImagePNGRepresentation(image);
}
/**
 *  截取當(dāng)前屏幕
 */
+ (UIImage *)imageWithScreenshot {
    CGSize imageSize = CGSizeZero;
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (UIInterfaceOrientationIsPortrait(orientation))
        imageSize = [UIScreen mainScreen].bounds.size;
    else
        imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        CGContextSaveGState(context);
        CGContextTranslateCTM(context, window.center.x, window.center.y);
        CGContextConcatCTM(context, window.transform);
        CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
        if (orientation == UIInterfaceOrientationLandscapeLeft) {
            CGContextRotateCTM(context, M_PI_2);
            CGContextTranslateCTM(context, 0, -imageSize.width);
        } else if (orientation == UIInterfaceOrientationLandscapeRight) {
            CGContextRotateCTM(context, -M_PI_2);
            CGContextTranslateCTM(context, -imageSize.height, 0);
        } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            CGContextRotateCTM(context, M_PI);
            CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
        }
        if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
            [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
        } else {
            [window.layer renderInContext:context];
        }
        CGContextRestoreGState(context);
    }
    return UIGraphicsGetImageFromCurrentImageContext();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末墩弯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子寞射,更是在濱河造成了極大的恐慌,老刑警劉巖锌钮,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡兄渺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門旺韭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人掏觉,你說(shuō)我怎么就攤上這事区端。” “怎么了澳腹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵织盼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我酱塔,道長(zhǎng)沥邻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任羊娃,我火速辦了婚禮唐全,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕊玷。我一直安慰自己邮利,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布垃帅。 她就那樣靜靜地躺著延届,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挺智。 梳的紋絲不亂的頭發(fā)上祷愉,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音赦颇,去河邊找鬼二鳄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛媒怯,可吹牛的內(nèi)容都是我干的订讼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼扇苞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼欺殿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鳖敷,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤脖苏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后定踱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體棍潘,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亦歉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恤浪。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肴楷,靈堂內(nèi)的尸體忽然破棺而出水由,到底是詐尸還是另有隱情,我是刑警寧澤赛蔫,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布砂客,位于F島的核電站,受9級(jí)特大地震影響濒募,放射性物質(zhì)發(fā)生泄漏鞭盟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一瑰剃、第九天 我趴在偏房一處隱蔽的房頂上張望齿诉。 院中可真熱鬧,春花似錦晌姚、人聲如沸粤剧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抵恋。三九已至,卻和暖如春宝磨,著一層夾襖步出監(jiān)牢的瞬間弧关,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工唤锉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留世囊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓窿祥,卻偏偏與公主長(zhǎng)得像株憾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晒衩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程嗤瞎,因...
    小菜c閱讀 6,404評(píng)論 0 17
  • 長(zhǎng)度與寬度是從不同的側(cè)面衡量的,萬(wàn)物都可以有長(zhǎng)度與寬度听系,有的如流星般劃過(guò)天空縣花一現(xiàn)贝奇,雖然很短暫,但綻放的美麗依然...
    妥了好的閱讀 372評(píng)論 0 0
  • 童話有如夢(mèng)想的花骨朵開(kāi)在不諳世事的眸子里靠胜,童話是為孩童所撰寫(xiě)的故事弃秆,是大人不再相信的糖果届惋。然而髓帽,一個(gè)個(gè)可愛(ài)生動(dòng)的故...
    Istanbul閱讀 432評(píng)論 0 0
  • 子非魚(yú)菠赚,焉知魚(yú)之樂(lè) 最近南京的天氣燥熱異常,中午和同事出門吃飯郑藏,在地鐵站看到了這樣的一幕: 一群在附近辦公樓施工的...
    咪哆啦咪閱讀 302評(píng)論 0 0