Overlay alpha colour to UIImage - ios

I'm using the following code to overlay 0.5 alpha colour to UIImage. But it seems to be lagging. My image has the size of 2000x1500.
Are there any other ways to overlay alpha colour to UIImage fast?
Thanks.
// Tint the image
- (UIImage *)imageWithTint:(UIColor *)tintColor alpha:(CGFloat)alpha {
UIImage *image = self;
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
CGContextRef c = UIGraphicsGetCurrentContext();
[image drawInRect:rect];
CGContextSetFillColorWithColor(c, [[tintColor colorWithAlphaComponent:0.25] CGColor]);
CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
CGContextFillRect(c, rect);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}

Related

UIImage Add Grey tranparency

I want to do the following:
As you can see one image (selected) does not have a grey fade and the other (nonselected item) does not.
I have tried multiple solutions. Including coloring the images with a grey color
- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color {
UIGraphicsBeginImageContext(image.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -area.size.height);
CGContextSaveGState(context);
CGContextClipToMask(context, area, image.CGImage);
[color set];
CGContextFillRect(context, area);
CGContextRestoreGState(context);
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextDrawImage(context, area, image.CGImage);
UIImage *colorizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return colorizedImage;
}
However with this approach I run into an issue where if the bg of an image has a transparency the white below it shine through and it looks strange:
How can I detect the transparency and change the transparency to white? Or is there a better solution for doing this?
image = [self imageWithImage:image scaledToSize:CGSizeMake((self.collectionViewContainer.frame.size.width/3),90)];
UIImage *unSelected = [self colorizeImage:image withColor:[[UIColor grayColor] colorWithAlphaComponent:.9]];
UIImageView *imgView = [[UIImageView alloc] initWithImage:unSelected highlightedImage:image];
Since you simply want to apply a gray tint to an image, try it this way:
- (UIImage *)colorizeImage:(UIImage *)image withColor:(UIColor *)color {
UIGraphicsBeginImageContext(image.size, NO, image.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, image.size.width, image.size.height);
[image drawInRect:area];
[color set];
CGContextFillRect(context, area);
UIImage *colorizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return colorizedImage;
}
This draws the image and then draws the color over the image. Assuming the color is partially transparent, the entire new image will be colored.
As you had it originally, you were only coloring the non-transparent parts due to the image clipping.
This update also applies the proper scale to the new image to match the original image.

iOS create UIImage using a mask and a UIColor

I'm currently coloring an existing image using a mask. For example, I have a white image with a black border and a circular mask (like the first two images). Then, I can create a third image with a color (i.e. green) which has green on the center of the original image (because the mask is present there).
The code I'm using is this (suggestions welcomed):
-(UIImage *)paintWithMask:(UIImage *)mask color:(UIColor *)color andSize:(CGSize)size{
UIImage *image = self;
UIImage *rotatedMask = [self rotateImage:mask]; //For some reason this is needed.
UIGraphicsBeginImageContextWithOptions(size, NO, image.scale);
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
[image drawInRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextClipToMask(context, rect, [rotatedMask CGImage]);
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
What I need to do now is paint the green circle using only the mask (without the black border obviously), like this:
Any ideas? Thanks a lot!!
There is a much easier way of doing this without CoreGraphics. Simply do the following:
-(UIImageView *)imageViewWithMask:(UIImage *)mask color:(UIColor *)color andSize:(CGSize)size{
UIImage *tempImage = mask;
tempImage = [tempImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(size, NO,0);
[tempImage drawInRect: CGRectMake(0,0,size.width,size.height)];
tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *iv = [[UIImageView alloc] initWithImage: tempImage];
iv.tintColor = color;
return iv;
}

IOS: color only the transparent pixels

If I have an image with some transparent pixels, is there any possibility to color the transparent pixels with white and make the rest of the image transparent in objective-c?
Thanks!
I found a solution:
- (UIImage*)convertToInverseWhiteMask: (UIImage *) image {
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
CGRect imageRect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// Draw a white background (for white mask)
CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
CGContextFillRect(ctx, imageRect);
// Apply the source image's alpha
[image drawInRect:imageRect blendMode:kCGBlendModeDestinationOut alpha:1.0f];
UIImage* mask = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return mask;
}
Here is what i am using:
- (UIImage *)imageWithTintedColor:(UIImage *)image withTint:(UIColor *)color withIntensity:(float)alpha
{
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, FALSE, [[UIScreen mainScreen] scale]);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextSetBlendMode(context, kCGBlendModeSourceAtop);
CGContextSetAlpha(context, alpha);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, image.size.width, image.size.height));
UIImage * tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}

Draw UIImage on a custom color canvas

I want to draw a image for example on black canvas, but the the result is always white, here is my code
-(UIImage*) renderImage
{
UIGraphicsBeginImageContext(CGSizeMake(300, 300));
[[UIColor blackColor] setFill];
UIImage*resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
for the future i will draw an image inside the canvas, but right now i just want a black filled canvas. why this code is not working
You need to be using CGContextSetFillColorWithColor() to fill the current context with a color. Try this sample code, you give it a color and a size and it will return you a UIImage meeting your criteria.
- (UIImage *)renderImageWithColor:(UIColor *)color inSize:(CGSize)size
{
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

Image coloring/masking foreground using blending

I'm trying to change the color of an image at runtime. I've seen a couple answers on SO, but they all change the background color and not the foreground, which is what I am trying to do. I've based my code on another SO thread.
Here's the code I have:
#implementation UIImage (Coloring)
-(UIImage*) imageWithColorOverlay:(UIColor*)color
{
//create context
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// drawingcode
//bg
CGRect rect = CGRectMake(0.0, 0.0, self.size.width, self.size.height);
[self drawInRect:rect];
//fg
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//end
return image;
}
#end
This are the results thus far:
From left to right:
No blending, just the normal asset. The gray bg is from the UIView behind the imageviews, the bg of the image is transparent.
Multiply with kCGBlendModeMultiply
Color burn with kCGBlendModeColorBurn
Is there an CGBlendMode that'll achieve replacing the foreground color? Also, is it possible to replace both the foreground color(white) and the shadow(black)?
After messing around with the different blend options, this code did the trick. The only caveat is that the red tint is shown in the shadow, its not technically correct but its close enuf
#implementation UIImage (Coloring)
-(UIImage*) imageWithColorOverlay:(UIColor*)color
{
//create context
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
//drawingcode
//bg
CGRect rect = CGRectMake(0.0, 0.0, self.size.width, self.size.height);
[self drawInRect:rect];
//fg
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
//mask
[self drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0];
//end
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

Resources