2016-02-18 41 views
3

我想更改不透明的UIImage的顏色。我原來的圖像如下:如何用不透明的UIImage替換另一個給定的顏色

enter image description here

,我想將圖像轉換爲以下格式

enter image description here

所以,基本上我想紅色顏色轉換圖像中分成黑色(任何其他顏色)的顏色。爲了更好的理解,上面添加了兩張圖片。

+2

檢查這.... .... http://stackoverflow.com/questions/12396236/ios-change-the-colors-of-a-uiimage –

+0

你只是將紅色區域轉換爲黑色,或提取紅色區域到一個新的黑色圖像?我問,因爲第二張圖片沒有顯示第一張存在於第一張的影子 – Russell

+0

@Russell:我想簡單地將紅色區域轉換爲黑色。 – iPhone

回答

10

我看不出在「重複」(這個問題不應該被標記爲重複),可以讓你用另一種顏色正常工作中更換指定顏色的任何答案不透明的圖像,所以我決定添加一個。


我創建了一個UIImage類別要做到這一點,它基本上是通過每個像素的循環和檢測它是一個給定的顏色多麼接近,並與您更換顏色混合,如果它是工作。

這將適用於圖像與透明度和不透明的背景

@implementation UIImage (UIImageColorReplacement) 

-(UIImage*) imageByReplacingColor:(UIColor*)sourceColor withMinTolerance:(CGFloat)minTolerance withMaxTolerance:(CGFloat)maxTolerance withColor:(UIColor*)destinationColor { 

    // components of the source color 
    const CGFloat* sourceComponents = CGColorGetComponents(sourceColor.CGColor); 
    UInt8* source255Components = malloc(sizeof(UInt8)*4); 
    for (int i = 0; i < 4; i++) source255Components[i] = (UInt8)round(sourceComponents[i]*255.0); 

    // components of the destination color 
    const CGFloat* destinationComponents = CGColorGetComponents(destinationColor.CGColor); 
    UInt8* destination255Components = malloc(sizeof(UInt8)*4); 
    for (int i = 0; i < 4; i++) destination255Components[i] = (UInt8)round(destinationComponents[i]*255.0); 

    // raw image reference 
    CGImageRef rawImage = self.CGImage; 

    // image attributes 
    size_t width = CGImageGetWidth(rawImage); 
    size_t height = CGImageGetHeight(rawImage); 
    CGRect rect = {CGPointZero, {width, height}}; 

    // bitmap format 
    size_t bitsPerComponent = 8; 
    size_t bytesPerRow = width*4; 
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; 

    // data pointer 
    UInt8* data = calloc(bytesPerRow, height); 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // create bitmap context 
    CGContextRef ctx = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); 
    CGContextDrawImage(ctx, rect, rawImage); 

    // loop through each pixel's components 
    for (int byte = 0; byte < bytesPerRow*height; byte += 4) { 

     UInt8 r = data[byte]; 
     UInt8 g = data[byte+1]; 
     UInt8 b = data[byte+2]; 

     // delta components 
     UInt8 dr = abs(r-source255Components[0]); 
     UInt8 dg = abs(g-source255Components[1]); 
     UInt8 db = abs(b-source255Components[2]); 

     // ratio of 'how far away' each component is from the source color 
     CGFloat ratio = (dr+dg+db)/(255.0*3.0); 
     if (ratio > maxTolerance) ratio = 1; // if ratio is too far away, set it to max. 
     if (ratio < minTolerance) ratio = 0; // if ratio isn't far enough away, set it to min. 

     // blend color components 
     data[byte] = (UInt8)round(ratio*r)+(UInt8)round((1.0-ratio)*destination255Components[0]); 
     data[byte+1] = (UInt8)round(ratio*g)+(UInt8)round((1.0-ratio)*destination255Components[1]); 
     data[byte+2] = (UInt8)round(ratio*b)+(UInt8)round((1.0-ratio)*destination255Components[2]); 

    } 

    // get image from context 
    CGImageRef img = CGBitmapContextCreateImage(ctx); 

    // clean up 
    CGContextRelease(ctx); 
    CGColorSpaceRelease(colorSpace); 
    free(data); 
    free(source255Components); 
    free(destination255Components); 

    UIImage* returnImage = [UIImage imageWithCGImage:img]; 
    CGImageRelease(img); 

    return returnImage; 
} 

@end 

用法:

UIImage* colaImage = [UIImage imageNamed:@"cola1.png"]; 
UIImage* blackColaImage = [colaImage imageByReplacingColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:1] withMinTolerance:0.5 withMaxTolerance:0.6 withColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:1]]; 

minTolerance是在哪些像素將開始與更換顏色(而不是被取代)以混合點。 maxTolerance是像素將停止混合的點。

前:

enter image description here

後:

enter image description here

結果是有點走樣,但請記住,你的原始圖像是相當小的。這對於更高分辨率的圖像會更好。您還可以玩容差以獲得更好的結果!

+0

很棒!嘗試了一些其他的解決方案,但這是一個現貨。 – trdavidson

+0

你能用Swift 3重寫嗎? –

+0

肯定的最佳答案。我翻譯爲Swift 3 [replaceColor.swift](http://www.realadsb.com/dl/replaceColor.swift) –

0

您可以使用此

theImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 
    [theImageView setTintColor:[UIColor blackColor]]; 

我覺得有什麼不對您的形象在這裏是我的形象,它是白色的。 enter image description here

這裏是在模擬器 enter image description here

+0

是的,這是我的測試代碼,它正在工作。 –

+4

問題中的圖像具有白色背景,這隻適用於透明的PNG。 –

0

注意的變化:首先,您需要設置圖像的背景爲透明使用Photoshop或其他任何工具。

然後使用下面的代碼。

簡單的方法, 你需要使用渲染模式來改變這種顏色。

cokeImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; // yourimageviewname 
[cokeImageView setTintColor:[UIColor blackColor]]; 
+0

當我應用上面的代碼時,我的整個imageview被轉換成黑色 – iPhone

+0

它首先測試它的工作。如果沒有測試代碼,不要給出負面標記。我總是使用這種方法。 –

+1

問題中的圖像具有白色背景,這隻適用於透明的PNG。 –

相關問題