UIImage color change?

How can I change the color of UIImage using programming, any help please? If I send UIImage, should its color change any help please? If I changed the color of RGB using bitmapping, this will not work.

+17
iphone
Nov 09 '09 at 3:37
source share
11 answers

If you only need to look different, just use imageView.tintColor (iOS 7+). Catch, setting tintColor by default does not:

Why isn't my image blue? I'm setting tintColor ...

To do the job, use 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 

And now it will work:

Now the image is orange!

Documentation Link




Performance

Customizing the image after setting up UIImageView avoids costly operations:

 // 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 

Getting and adjusting the image asynchronously reduces the scroll and delay of the animation (especially when tinting the image inside a UICollectionViewCell or UITableViewCell ):

 let imageView = cell.yourImageView imageView.image = nil // Clear out old image imageView.tintColor = UIColor(red: 0.35, green: 0.85, blue: 0.91, alpha: 1) // Setting the image asynchronously reduces stuttering // while scrolling. Remember, the image should be set as // late as possible to avoid repeating expensive operations // unnecessarily. dispatch_async(dispatch_get_main_queue(), { () -> Void in var image = UIImage(named: "stackoverflow")! image = image.imageWithRenderingMode(.AlwaysTemplate) imageView.image = image }) 
+36
Jul 18 '14 at 22:03
source share

One way to achieve this is to discolor the image and add a tint on top of that image with the desired color.

Desaturate

 -(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; } 

Overlay with color

 -(UIImage *) getImageWithTintedColor:(UIImage *)image withTint:(UIColor *)color withIntensity:(float)alpha { CGSize size = image.size; UIGraphicsBeginImageContextWithOptions(size, FALSE, 2); CGContextRef context = UIGraphicsGetCurrentContext(); [image drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0]; CGContextSetFillColorWithColor(context, color.CGColor); CGContextSetBlendMode(context, kCGBlendModeOverlay); CGContextSetAlpha(context, alpha); CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, image.size.width, image.size.height)); UIImage * tintedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return tintedImage; } 

How-to

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

You can change the color of the hue as you want.

+7
Mar 30 2018-12-12T00:
source share

Send a message (basically just a remix code) .

Change This code basically creates a new CGContext , overlays it with a new color and returns a new UIImage from it. For some time I did not delve into this code, but it just draws a UIImage with the same shape as the original, so that is the limit (it loses any detail in the image).

+2
Dec 13 '10 at 23:28
source share

There's a great post about it here: http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage

One of the caveats I have with the current code is that using it on retina images will result in a loss of higher resolution for these images. I'm currently looking for a solution for this ...

+2
May 24 '11 at 17:26
source share

If you need high performance, I highly recommend that you use GPUImage . You can download it at https://github.com/BradLarson/GPUImage

+2
Jul 18 '14 at 22:09
source share

The RGB data you're working on is just a copy. After you finish making changes, you need to return the data back to the image.

First, create a new bitmap:

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

And get the pixels:

 pixels = CGBitmapContextGetData( ctx ); 

Assuming your pixel data comes from pixels = CGBitmapContextGetData( ctx ); , then take this context and create a new image from it:

 CGImageRef newImg = CGBitmapContextCreateImage(ctx); [[UIImage imageWithCGImage:newImg] drawInRect:rect]; CGImageRelease(newImg); 
+1
Nov 09 '09 at 9:18
source share

I think you can create a different context by setting the context color to RGB that you want to color. Then draw a UIImage in this context and use this context instead of directly using your photo. This is a concept. This way you create a screen buffer with a color image. I have not tried this in cocoa, only in carbon, but I believe that it will work the same.

0
Nov 09 '09 at 7:14
source share

Hmmm is not the byte order, which should be RGBA? You install them as ARGB ...

0
Jan 04 '10 at 21:17
source share

try it

 - (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; } 
0
Sep 24 '13 at 12:54 on
source share

Great article mentioned by user 576924 did a great job for me: iPhone: how to dynamically color UIImage

and fast:

 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 } 

}

Please note that I also changed "kCGBlendModeColorBurn" to "kCGBlendModeColor" as indicated in the comment section for comments.

0
Mar 09 '15 at 23:53
source share

For me it worked:

 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 } } 
0
Jul 03 '15 at 12:51
source share



All Articles