如何用一个不透明的UIImagereplace另一个给定的颜色

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

在这里输入图像说明

我想将图像转换为以下格式

在这里输入图像说明

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

我看不到任何关于'重复'的答案(这个问题不应该被标记为重复),这将允许你用另一种颜色replace给定的颜色, 在不透明的图像上工作,所以我决定添加一个将。


我创build了一个UIImage类来做到这一点,它基本上是通过循环遍历每个像素,并检测它与给定颜色的接近程度,并将其与您的replace颜色混合(如果是)。

这将适用于具有透明度和不透明背景的图像。

 @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是像素将开始与replace颜色混合(而不是被replace)的点。 maxTolerance是像素停止混合的点。

之前:

在这里输入图像说明

后:

在这里输入图像说明

结果是有点别名,但要记住,你的原始图像是相当小的。 这将更好的分辨率更高的图像。 你也可以玩容忍,以获得更好的结果!

你可以使用这个

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

我认为这里的形象不对,就是我的形象,它是白色的。 在这里输入图像说明

这里是模拟器的变化 在这里输入图像说明

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

然后使用下面的代码。

简单的方法,你需要使用渲染模式来改变这种颜色。

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