Iphone 图像颜色改变?

Iphone 图像颜色改变?,iphone,Iphone,如何通过编程更改UIImage的颜色,请提供帮助?如果我发送一个UIImage,它的颜色需要更改,请提供帮助?如果我通过位图处理更改RGB颜色,它将不起作用。我认为您可以创建另一个上下文,将上下文颜色设置为要为图片上色的RGB。然后将UIImage绘制到该上下文中,并使用该上下文,而不是直接使用图片。这是一个概念。这样,您就可以用彩色图像创建屏幕外缓冲区。我没有在可可粉中尝试,只是在碳纤维中,但我想它也会以同样的方式工作。您正在操作的RGB数据只是一个副本。完成更改后,需要将该数据转换回图像 我

如何通过编程更改UIImage的颜色,请提供帮助?如果我发送一个UIImage,它的颜色需要更改,请提供帮助?如果我通过位图处理更改RGB颜色,它将不起作用。

我认为您可以创建另一个上下文,将上下文颜色设置为要为图片上色的RGB。然后将UIImage绘制到该上下文中,并使用该上下文,而不是直接使用图片。这是一个概念。这样,您就可以用彩色图像创建屏幕外缓冲区。我没有在可可粉中尝试,只是在碳纤维中,但我想它也会以同样的方式工作。

您正在操作的RGB数据只是一个副本。完成更改后,需要将该数据转换回图像

我首先创建一个新位图:

CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
ctx = CGBitmapContextCreate( malloc(dataSize), width, height,
                                8, //   CGImageGetBitsPerComponent(cgImage),
                                bytesPerRow, //CGImageGetBytesPerRow(cgImage),
                                space,
                                //kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big );
                                kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
                                //kCGImageAlphaPremultipliedFirst  | kCGBitmapByteOrder32Little);

    CGColorSpaceRelease( space );

// now draw the image into the context
CGRect rect = CGRectMake( 0, 0, CGImageGetWidth(cgImage), CGImageGetHeight(cgImage) );
CGContextDrawImage( ctx, rect, cgImage );
并获取像素:

pixels = CGBitmapContextGetData( ctx );
假设您的像素数据来自
pixels=CGBitmapContextGetData(ctx)然后获取该上下文并从中构建新图像:

CGImageRef newImg = CGBitmapContextCreateImage(ctx);
[[UIImage imageWithCGImage:newImg] drawInRect:rect];
CGImageRelease(newImg);
嗯,字节的顺序不是应该是RGBA吗?您正在将它们设置为ARGB…

请查看我的


编辑:此代码基本上创建一个新的
CGContext
,用新颜色在其上绘制一层,并从中返回一个新的
UIImage
。我已经有一段时间没有深入研究这段代码了,但它似乎只是画了一幅与原作形状相同的
UIImage
,所以这是一个限制(在图像中丢失任何细节)。

这里有一篇关于这一点的文章:


我对当前代码的一个警告是,在视网膜图像上使用它将导致这些图像失去更高的“分辨率”。我目前正在寻找一种解决方案…

实现这一点的一种方法是降低图像的饱和度,并在图像顶部添加一种您想要的颜色

去饱和

-(UIImage *) getImageWithUnsaturatedPixelsOfImage:(UIImage *)image {
    const int RED = 1, GREEN = 2, BLUE = 3;

    CGRect imageRect = CGRectMake(0, 0, image.size.width*2, image.size.height*2);

    int width = imageRect.size.width, height = imageRect.size.height;

    uint32_t * pixels = (uint32_t *) malloc(width*height*sizeof(uint32_t));
    memset(pixels, 0, width * height * sizeof(uint32_t));

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

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

    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t * rgbaPixel = (uint8_t *) &pixels[y*width+x];
            uint32_t gray = (0.3*rgbaPixel[RED]+0.59*rgbaPixel[GREEN]+0.11*rgbaPixel[BLUE]);

            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }

    CGImageRef newImage = CGBitmapContextCreateImage(context);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);

    UIImage * resultUIImage = [UIImage imageWithCGImage:newImage scale:2 orientation:0];
    CGImageRelease(newImage);

    return resultUIImage;
}
如何

//For a UIImageView
yourImageView.image = [self getImageWithUnsaturatedPixelsOfImage:yourImageView.image];
yourImageView.image = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];

//For a UIImage
yourImage = [self getImageWithUnsaturatedPixelsOfImage:yourImage];
yourImage = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
您可以根据自己的需要更改色调。

试试这个

- (UIImage *)imageWithOverlayColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);

    if (UIGraphicsBeginImageContextWithOptions) {
        CGFloat imageScale = 1.0f;
        if ([self respondsToSelector:@selector(scale)])  // The scale property is new with iOS4.
            imageScale = self.scale;
        UIGraphicsBeginImageContextWithOptions(self.size, NO, imageScale);
    }
    else {
        UIGraphicsBeginImageContext(self.size);
    }

    [self drawInRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(context, kCGBlendModeSourceIn);

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
如果您只需要它看起来不同,只需使用
imageView.tintColor
(iOS 7+)。问题是,默认情况下,设置
tintColor
不会执行任何操作:

要使其正常工作,请使用
imageWithRenderingMode:

var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)

let imageView = ...
imageView.tintColor = UIColor(red: 0.35, green: 0.85, blue: 0.91, alpha: 1)
imageView.image = image
现在它将起作用:


性能

-(UIImage *) getImageWithUnsaturatedPixelsOfImage:(UIImage *)image {
    const int RED = 1, GREEN = 2, BLUE = 3;

    CGRect imageRect = CGRectMake(0, 0, image.size.width*2, image.size.height*2);

    int width = imageRect.size.width, height = imageRect.size.height;

    uint32_t * pixels = (uint32_t *) malloc(width*height*sizeof(uint32_t));
    memset(pixels, 0, width * height * sizeof(uint32_t));

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);

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

    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            uint8_t * rgbaPixel = (uint8_t *) &pixels[y*width+x];
            uint32_t gray = (0.3*rgbaPixel[RED]+0.59*rgbaPixel[GREEN]+0.11*rgbaPixel[BLUE]);

            rgbaPixel[RED] = gray;
            rgbaPixel[GREEN] = gray;
            rgbaPixel[BLUE] = gray;
        }
    }

    CGImageRef newImage = CGBitmapContextCreateImage(context);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);

    UIImage * resultUIImage = [UIImage imageWithCGImage:newImage scale:2 orientation:0];
    CGImageRelease(newImage);

    return resultUIImage;
}
配置
UIImageView
后设置映像可避免重复昂贵的操作:

// Good usage
let imageView = ...
imageView.tintColor = yourTintColor
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
imageView.image = image        // Expensive

// Bad usage
var image = UIImage(named: "stackoverflow")!
image = image.imageWithRenderingMode(.AlwaysTemplate)
let imageView = ...
imageView.image = image        // Expensive
imageView.frame = ...          // Expensive
imageView.tintColor = yourTint // Expensive
异步获取和设置图像可减少滚动和动画延迟(尤其是在
UICollectionViewCell
UITableViewCell
中着色图像时):


如果您需要高性能,我强烈建议您使用
GPUImage

您可以从

下载,用户576924提到的伟大帖子对我来说非常有用:

以迅捷的速度:

extension UIImage {

    func imageWithColor( color : UIColor ) -> UIImage {

       // begin a new image context, to draw our colored image onto
       UIGraphicsBeginImageContext(self.size)

       // get a reference to that context we created
       let context = UIGraphicsGetCurrentContext();

       // set the fill color
       color.setFill()

       // translate/flip the graphics context (for transforming from CG* coords to UI* coords
       CGContextTranslateCTM(context, 0, self.size.height)
       CGContextScaleCTM(context, 1.0, -1.0)

       // set the blend mode to color burn, and the original image
       CGContextSetBlendMode(context, kCGBlendModeColor)
       let rect = CGRect(origin: CGPointZero, size: self.size)
       CGContextDrawImage(context, rect, self.CGImage)

       // set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
       CGContextClipToMask(context, rect, self.CGImage)
       CGContextAddRect(context, rect)
       CGContextDrawPath(context,kCGPathFill)

       // generate a new UIImage from the graphics context we drew onto
       let coloredImg = UIGraphicsGetImageFromCurrentImageContext()
       UIGraphicsEndImageContext()

       //return the color-burned image
       return coloredImg
   }
}

请注意,我还将“kCGBlendModeColorBurn”更改为“kCGBlendModeColorBurn”,如帖子评论部分所述。

对我来说,这很有效:

extension UIImage {
    class func image(image: UIImage, withColor color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width, image.size.height), false, image.scale)
        let context = UIGraphicsGetCurrentContext()
        color.set()
        CGContextTranslateCTM(context, 0, image.size.height)
        CGContextScaleCTM(context, 1, -1)
        let rect = CGRectMake(0, 0, image.size.width, image.size.height)
        CGContextClipToMask(context, rect, image.CGImage)
        CGContextFillRect(context, rect)
        let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return coloredImage
    }
}


这个类不只是一个图像而不是一种颜色吗?你到底在问什么?我想以编程的方式更改UIimage的颜色…当我这样调用[self-changeImagecolor:myImage color:[UIColor redcolor]]时,函数假设;函数必须返回我提到的带有颜色的图像。。。。。我知道我必须使用位图数据。。。你能帮忙吗?你可以查看这个链接。它工作得很好。你能接受答案吗?我使用UIGraphicsBeginImageContext从图像中获取上下文。但它不起作用?请看这个帖子:所以首先将该上下文中的当前颜色设置为要为图片上色的RGB,然后绘制图片。完成后,使用您创建的上下文,而不是原始图片。它是否适合您?我试过了,它没有给出结果吗?你做错了什么,我不能告诉你它是什么而不知道你在更改位图后做了什么。你如何把它变回图像?在StackOverflow上搜索“[iphone]位图图像”。这里有大量的问题和答案。为了确保您正确获取像素数据,请阅读此内容。我完全按照苹果的要求做了,请再次查看我的问题。。。。。?返回的图像不是黑色的…bcos我使用了r-0、g-0、b-0。请忽略透明部分。嘿,这很好,但我注意到,在具有透明度的PNG文件上使用这两种方法时,即使透明像素也会着色。任何解决方案?要使用源alpha将源颜色覆盖为您的颜色,请使用此混合模式(R=S*Da):CGContextSetBlendMode(上下文,kCGBlendModeSourceIn);在方法GetImageWithTintedColor中,原始代码不适用于灰色,但注释是正确的。实际上附加的图像是不正确的。它的背景是白色的,但应该是透明的。@Voloda2你说得对,你需要一个透明的图像。它在目标cI中如何运行?我在
UIBarButtonItem中使用的
UIButton
有这个问题。应该设置哪个图像?我用
setImage(for:.normal)
配置了我在按钮中设置的图像,但没有什么区别。我发现这个链接最适合我。我所做的唯一改变是在那篇文章的评论中推荐的:使用kCGBlendModeColor而不是kCGBlendModeColorBurn使混合模式工作得更好。我还用swift重写了它-请参阅我的其他关于该线程的答案。我得到一个错误,即“kCGPathFill”是一个未解析的标识符。我需要进口什么?谢谢
extension UIImage {
    class func image(image: UIImage, withColor color: UIColor) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(image.size.width, image.size.height), false, image.scale)
        let context = UIGraphicsGetCurrentContext()
        color.set()
        CGContextTranslateCTM(context, 0, image.size.height)
        CGContextScaleCTM(context, 1, -1)
        let rect = CGRectMake(0, 0, image.size.width, image.size.height)
        CGContextClipToMask(context, rect, image.CGImage)
        CGContextFillRect(context, rect)
        let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return coloredImage
    }
}