2014-02-14 93 views
4

我正在使用具有不同主題顏色的應用程序,但我不想在項目中擁有太多的圖像資源(基本上不希望項目尺寸太大),是否可以使用一個圖像但不同的顏色?是否有可能以編程方式更改圖像的顏色?

謝謝!

+0

http://stackoverflow.com/questions/1223340/iphone-how-do-you-color-an-image/4630136#4630136和http://stackoverflow.com/questions/14292212/changing-在iphone-sdk中的圖像顏色和http://stackoverflow.com/questions/12396236/ios-change-the-colors-of-a-uiimage – iPatel

+0

@iPatel謝謝你讓我知道,我將檢查所有這些問題。 – user3288387

回答

6

我與馬特同意,你應該檢查CIFilter爲未來的圖像修改。但如果你正在尋找一個快速的代碼示例,下面是我如何做到這一點。工作對我來說相當不錯,只需要像這樣調用:

[self useColor:[UIColor redColor] forImage:WHATEVER_IMAGE]; 

- (UIImage *)useColor:(UIColor *)color forImage:(UIImage *)image 
{ 
    if(!color) 
     return image; 

    NSUInteger width = CGImageGetWidth([image CGImage]); 
    NSUInteger height = CGImageGetHeight([image CGImage]); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    NSUInteger bitsPerComponent = 8; 
    NSUInteger bitmapByteCount = bytesPerRow * height; 

    unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); 

    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
              bitsPerComponent, bytesPerRow, colorSpace, 
              kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]); 

    CGColorRef cgColor = [color CGColor]; 
    const CGFloat *components = CGColorGetComponents(cgColor); 
    float r = components[0] * 255.0; 
    float g = components[1] * 255.0; 
    float b = components[2] * 255.0; 
    //float a = components[3]; // not needed 

    int byteIndex = 0; 

    while (byteIndex < bitmapByteCount) 
    { 
     int oldR = rawData[byteIndex]; 
     int oldG = rawData[byteIndex + 1]; 
     int oldB = rawData[byteIndex + 2]; 
     int oldA = rawData[byteIndex + 3]; 
     if(oldR != 0 || oldG != 0 || oldB != 0 || oldA != 0) 
     { 
      rawData[byteIndex] = r; 
      rawData[byteIndex + 1] = g; 
      rawData[byteIndex + 2] = b; 
     } 

     byteIndex += 4; 
    } 

    UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context) scale:image.scale orientation:image.imageOrientation]; 

    CGContextRelease(context); 
    free(rawData); 

    return result; 
} 
+0

工作,謝謝! – user3288387

0

一個更簡單的回答:如果你的圖像可以是顏色(例如線圖),然後就指定要UIImageRenderingModeAlwaysTemplate。現在圖像將採用其容器的tintColor,因此只需更改tintColor即可更改其顏色。

0

基於Xu Yin's answer - 這更好的擬合SVG狀圖標那些在他們圓形圖案(並因此可能通過程序的原始版本像素化)的一個版本。

這個改變只是當前alpha級別對每個像素值的使用(乘法)。

- (UIImage *)useColor:(UIColor *)color forImage:(UIImage *)image { 
    if(!color) 
     return image; 

    NSUInteger width = CGImageGetWidth([image CGImage]); 
    NSUInteger height = CGImageGetHeight([image CGImage]); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    NSUInteger bytesPerPixel = 4; 
    NSUInteger bytesPerRow = bytesPerPixel * width; 
    NSUInteger bitsPerComponent = 8; 
    NSUInteger bitmapByteCount = bytesPerRow * height; 

    unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); 

    CGContextRef context = CGBitmapContextCreate(rawData, width, height, 
               bitsPerComponent, bytesPerRow, colorSpace, 
               kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [image CGImage]); 

    CGColorRef cgColor = [color CGColor]; 
    const CGFloat *components = CGColorGetComponents(cgColor); 
    float r = components[0] * 255.0; 
    float g = components[1] * 255.0; 
    float b = components[2] * 255.0; 

    int byteIndex = 0; 

    while (byteIndex < bitmapByteCount) { 
     int oldR = rawData[byteIndex]; 
     int oldG = rawData[byteIndex + 1]; 
     int oldB = rawData[byteIndex + 2]; 
     int oldA = rawData[byteIndex + 3]; 
     if(oldR != 0 || oldG != 0 || oldB != 0 || oldA != 0) { 
      rawData[byteIndex] = r * (oldA/255.0); 
      rawData[byteIndex + 1] = g * (oldA/255.0); 
      rawData[byteIndex + 2] = b * (oldA/255.0); 
     } 

     byteIndex += 4; 
    } 

    UIImage *result = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context) scale:image.scale orientation:image.imageOrientation]; 

    CGContextRelease(context); 
    free(rawData); 

    return result; 
} 
相關問題