Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在不透明图像上用另一种颜色替换给定颜色_Ios_Objective C_Uiimageview_Uiimage - Fatal编程技术网

Ios 如何在不透明图像上用另一种颜色替换给定颜色

Ios 如何在不透明图像上用另一种颜色替换给定颜色,ios,objective-c,uiimageview,uiimage,Ios,Objective C,Uiimageview,Uiimage,我想更改不透明图像的颜色。我的原始图像如下: 我想把图像转换成以下格式 因此,基本上我想将图像中的红色颜色转换为黑色(任何其他颜色)颜色。添加以上两幅图像是为了更好地理解。您可以使用此图像。 theImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [theImageView setTintColor:[UIColor blackColor]]; 我觉得你的照片

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

我想把图像转换成以下格式


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

您可以使用此图像。

  theImageView.image = [image  imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
   [theImageView setTintColor:[UIColor blackColor]];
我觉得你的照片有点不对劲,这是我的照片,是白色的

这里是模拟器的变化
您可以使用此

  theImageView.image = [image  imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
   [theImageView setTintColor:[UIColor blackColor]];
我觉得你的照片有点不对劲,这是我的照片,是白色的

这里是模拟器的变化

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

然后使用下面的代码

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

cokeImageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; // yourimageviewname 
[cokeImageView setTintColor:[UIColor blackColor]];
注意:首先,您需要使用Photoshop或任何其他工具将图像背景设置为透明

然后使用下面的代码

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

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

我看不到关于“副本”(这个问题不应该被标记为副本)的任何答案,这些副本可以让你用另一种颜色替换给定的颜色并处理不透明图像,因此我决定添加一个这样的答案。


我创建了一个
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
minTolerance
是像素开始与替换颜色混合(而不是被替换)的点。
maxTolerance
是像素停止混合的点

之前:

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]];

之后:

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]];


结果是有点锯齿,但请记住,原始图像相当小。这将更好地用于更高分辨率的图像。您还可以使用公差来获得更好的结果

我看不到关于“副本”(这个问题不应该被标记为副本)的任何答案,这些副本可以让你用另一种颜色替换给定的颜色并处理不透明图像,因此我决定添加一个这样的答案。


我创建了一个
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
minTolerance
是像素开始与替换颜色混合(而不是被替换)的点。
maxTolerance
是像素停止混合的点

之前:

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]];

之后:

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]];



结果是有点锯齿,但请记住,原始图像相当小。这将更好地用于更高分辨率的图像。您还可以使用公差来获得更好的结果

检查这个。。。。您只是将红色区域转换为黑色,还是将红色区域提取为新的黑色图像?我这样问是因为第二张图像没有显示出图像中的阴影first@Russell:我只想将红色区域转换为黑色。请检查此。。。。您只是将红色区域转换为黑色,还是将红色区域提取为新的黑色图像?我这样问是因为第二张图像没有显示出图像中的阴影first@Russell:我想简单地将红色区域转换为黑色。当我应用上述代码时,我的整个imageview将转换为黑色。首先工作,然后进行测试。在没有测试代码的情况下,不要给出否定标记。我总是使用这种方法。问题中的图像有白色背景,这只适用于透明PNG。您的图像中存在问题是的。MAC中支持PNG格式的实际方式在大多数情况下没有白色背景。图像应该是透明的,而不是白色背景。当我应用上面的代码时,我的整个图像视图被转换成黑色。首先,你测试它。在没有测试代码的情况下,不要给出否定标记。我总是使用这种方法。问题中的图像有白色背景,这只适用于透明PNG。您的图像中存在问题是的。MAC中支持PNG格式的实际方式在大多数情况下没有白色背景。图像应该是透明的,而不是白色背景。是的,这是我的测试代码,它正在工作。问题中的图像有白色背景,这将只在透明PNG上工作。这将显示为黑色,但实际上不会更改图像。是的,这是我的测试代码,它正在工作。问题中的图像有白色背景,这将只适用于透明PNG。这是显示为黑色,但实际上并没有改变图像。工程伟大!尝试了几个其他的解决方案,但这一个是正确的。你能用Swift 3重写它吗?肯定是最好的答案。我翻译成Swift 3作品很棒!尝试了几个其他的解决方案,但这一个是正确的。你能用Swift 3重写它吗?肯定是最好的答案。我翻译成Swift 3