CGImageRef or CGImageMaskCreate performance issue - ios

Wondering if you guys ever face the scrolling performance issue while using the codes as follows.
- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
Ok, so basically the codes above are doing image masking which I found from this site.
http://iosdevelopertips.com/cocoa/how-to-mask-an-image.html#comment-47347
And I've successfully integrate it to my project which bringing me some poor performance issue while scrolling the table view.
From what I've suspect is because each and every time the cell will keep "re-render" the image masking and cause the poor performance.

Related

Memory Increase When Masking Image

I am using the following code to create a masked UIImage. I am finding however that when i run the code multiple times the memory is increasing and not releasing. Can someone see where there may be a leak?
-(UIImage*)processImage:(UIImage *)sourceImage maskImage:(UIImage *)maskImage {
UIImage *editedImage = nil;
UIImage *mask = [self createMaskImage:maskImage canvasImage:sourceImage maskWidth:50 maskHeight:50];
editedImage = [self maskImage:sourceImage withMask:mask];
return editedImage;
}
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
Since you are using CoreGraphics, ARC will not work for you.
You are creating / allocating with CGImageCreateWithMask.
Then you need to remove it with CGImageRelease.
From Apple Documentation:
An image created by masking image with mask. You are responsible for releasing this object by calling CGImageRelease.
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
// Create image from CGImageRef
UIImage *myImage = [UIImage imageWithCGImage:masked];
// Release it
CGImageRelease(masked);
return myImage;
}

How to crop an image which is coming inside circle in iOS

I am working on a project where I need to show an screen same as below
Here the image should be cropped which is visible only in the circle. I have tried image masking as below. But it always crop in square.
- (UIImage*) maskImage1:(UIImage *) image withMask:(UIImage *) mask
{
CGImageRef imageReference = image.CGImage;
CGImageRef maskReference = mask.CGImage;
CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
CGImageGetHeight(maskReference),
CGImageGetBitsPerComponent(maskReference),
CGImageGetBitsPerPixel(maskReference),
CGImageGetBytesPerRow(maskReference),
CGImageGetDataProvider(maskReference),
NULL, // Decode is null
YES // Should interpolate
);
CGImageRef maskedReference = CGImageCreateWithMask(imageReference, imageMask);
CGImageRelease(imageMask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedReference];
CGImageRelease(maskedReference);
return maskedImage;
}
Please suggest how can I achieve this?
Use the demo to scale and crop image circle.Circle Image Crop
for Masking your image in to circle as below cede.
//Masking the image
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}
UIGraphicsBeginImageContextWithOptions(hiddenView.bounds.size, self.view.opaque, 0.0); //In this I have take screenshot of a hiddenView that I have added from IB with a background color anything( in this case it's orange).
//Replace this hiddenView object with your object of whom you want to take screenshot.
[hiddenView.layer renderInContext:UIGraphicsGetCurrentContext()]; //Similarly replace hiddenView here with your object.
UIImage*theImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData*theImageData=UIImageJPEGRepresentation(theImage, 1.0 );
imgView.image = [UIImage imageWithData:theImageData]; //I placed a UIImageView to check and place the screenshot into it as Image ,simply to cross check if I'm getting a right screenshot or not.
//So you could also remove this line after your have verified that your getting right screen shot.

How to crop an image in a desired shape

I'm trying to develop an easy game. But then, I came across this problem with my UIImage.
When I import an image, I get this annoying background on this ball, not just the ball itself. So when I play with this ball, this background has to match the UIView color, or else it will look weird. How do I solve this problem?
You can use following code to get a mask shape image with a mask:
//beCroppedImage is the image be cropped, maskImage is a image with a white background color and a black sharp that ever you want.
theShapeImage = [beCroppedImage maskImageWithMask:maskImage];
- (UIImage *)maskImageWithMask:(UIImage*)mask {
CGImageRef imgRef = [self CGImage];
CGImageRef maskRef = [mask CGImage];
CGImageRef actualMask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask(imgRef, actualMask);
UIImage *image = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);
CGImageRelease(actualMask);
return image;
}

Masking UIImage in ios

I'am trying to create profile picture image with custom shape pattern with using masking in ios. Here is what i've used to create masked image :
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(mask);
CGImageRelease(maskedImageRef);
// returns new image with mask applied
return maskedImage;
}
After implementing instance , i am calling : *(_profileImage is global UIImage)
UIImage *maskImage = [UIImage imageNamed:#"maskProfilePicture.png"];
UIImage *maskedImage = [self maskImage:_profileImage withMask:maskImage];
and result (Image should be added in subview of mask. But it seems , mask image overlap on Image that need to be masked ):
The mask image : (Maybe mask image properties are wrong that i created in photoshop :)
The Core Graphics calls look correct.
Change the mask image to be have a black where you want the image to show through, and white elsewhere.
You can use CALayer's mask property to achieve the result.
CALayer Apple Documentation
Your masking layer should be transparent in places where you want to cut out the image.

Image Blur/Quality Loss when Masking in iOS

I am masking an image (left) with this function
- (UIImage*)maskWithMask:(UIImage *)maskImage
{
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);
UIGraphicsBeginImageContextWithOptions(maskedImage.size,NO,0.0);
[maskedImage drawAtPoint:CGPointZero];
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImg;
}
after the mask the resulting image appears to have lost quality / blurred slightly as shown on the right of the photo. I cannot seam to figure out why. I know it isn't a major loss, but its enough to notice on a retina display, which is what I am developing on. Any thoughts?

Resources