如何在不透明的UIImage上用另一种颜色替换给定的颜色

时间:2016-02-18 09:20:31

标签: ios objective-c uiimageview uiimage

我想改变不透明UIImage的颜色。我的原始图片如下:

enter image description here

我希望将图片转换为以下格式

enter image description here

所以,基本上我想将图像中的红色颜色转换为黑色(任何其他颜色)颜色。添加以上两张图片是为了更好地理解。

3 个答案:

答案 0 :(得分:11)

我无法在“重复”中找到任何答案。 (这个问题不应该被标记为重复),它可以让你用另一种颜色替换给定的颜色在不透明的图像上工作,所以我决定添加一个。< /强>

我为此创建了一个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

结果有点混淆,但请记住,您的原始图像相当小。对于更高分辨率的图像,这将更好地工作。您也可以使用公差来获得更好的结果!

答案 1 :(得分:0)

您可以使用此

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

我认为你的形象出现问题的是我的形象,它是白色的。 enter image description here

这是模拟器的变化 enter image description here

答案 2 :(得分:0)

  

注意:首先,您需要使用Photoshop或任何其他工具将图像的背景设置为透明。

然后使用下面的代码。

简单的方法, 您需要使用渲染模式来更改此颜色。

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