gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 05:03:42 27 4
gpt4 key购买 nike

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

enter image description here

我想把图片转换成下面的格式

enter image description here

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

最佳答案

我看不到关于“重复项”的任何答案(这个问题不应该被标记为重复项)可以让您用另一种颜色替换给定颜色在一张不透明的图片上工作,所以我决定添加一张不透明的图片。


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

结果有点锯齿,但请记住,您的原始图像相当小。这对于更高分辨率的图像会更好。您还可以调整公差以获得更好的结果!

关于ios - 如何在不透明的 UIImage 上用另一种颜色替换给定颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35477327/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com