I have two images one is background image and one is masked image.
I am cropping background image based on masked image.
Background Image With Mask Image:
Result Image:
Following method is being used for cropping:
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (mainViewContentContext==NULL)
return NULL;
CGFloat ratio = 0;
ratio = maskImage.size.width/ image.size.width;
if(ratio * image.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ image.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;
}
Issue
Problem I am facing is that the mask Image is not taking the actual frame as shown above in background with mask image.
I tried playing with ratio and rect1 and rect2 but couldn't acheive the desired result.
Expected Image:
Image with exact frame of masked Image.
It would be great if someone show me the light.
Related
I am struggling between the logic of masking two UIImage. I want to mask baby face UIImage on mask UIImage. The biggest problem is size. If 2 UIImages are of same size and then I can do easily but when the sizes are different, it doesn't work!
Below are the solutions tried but none of them working as expected.
Solution 1
- (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;
}
Solution 2
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (mainViewContentContext==NULL)
return NULL;
CGFloat ratio = 0;
ratio = maskImage.size.width/ image.size.width;
if(ratio * image.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ image.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;
}
Update
Baby face image size is smaller than the mask image. So I want to mask image on the specific rect.
I have an iOS application. I take a picture from my camera and I save this then crop this with a mask. The first image from the camera is saved correctly, but when I apply the mask it is saved with a low resolution and a stretched image.
I'm using this Objective-C code into my application to apply the mask.
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)mask_Image {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//UIImage *maskImage = maskImage1;
CGImageRef maskImageRef = [mask_Image CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, mask_Image.size.width, mask_Image.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
if (mainViewContentContext==NULL)
return NULL;
CGFloat widthratio = 0;
CGFloat heightratio = 0;
widthratio = mask_Image.size.width / image.size.width;
heightratio = mask_Image.size.height / image.size.height;
CGRect rect1 = {{0, 0}, {mask_Image.size.width, mask_Image.size.height}};
CGRect rect2 = {{-((image.size.width*widthratio)-mask_Image.size.width)/2 , -((image.size.height*heightratio)-mask_Image.size.height)/2}, {image.size.width*widthratio, image.size.height*heightratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
NSData* imageData = UIImagePNGRepresentation(theImage); // get png representation
UIImage* pngImage = [UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil);
return theImage;
}
I want get this correctly like:
I take my picture from the camera:
I apply my mask image to the camera image in the position that I wanted:
And I get my cropped image masked:
How can I get the correct masked image?
I have two Images 1.Original image 2.mask image
I want to mask original image with mask image and it will done using below code.
- (UIImage *) maskImage:(UIImage *)originalImage : (NSString *)maskImageName
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIImage *maskImage = [UIImage imageNamed:maskImageName];
CGImageRef maskImageRef = [maskImage CGImage];
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);//kCGImageAlphaPremultipliedLast
CGColorSpaceRelease(colorSpace);
if (mainViewContentContext == NULL)
{
return NULL;
}
CGFloat ratio = 0;
ratio = maskImage.size.width/ originalImage.size.width;
if(ratio * originalImage.size.height < maskImage.size.height)
{
ratio = maskImage.size.height/ originalImage.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((originalImage.size.width*ratio)-maskImage.size.width)/2 , -((originalImage.size.height*ratio)-maskImage.size.height)/2}, {originalImage.size.width*ratio, originalImage.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);//rect1
CGContextDrawImage(mainViewContentContext, rect2, originalImage.CGImage);//rect2
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
CGImageRelease(maskImageRef);
CGColorSpaceRelease(colorSpace);
return theImage;
}
But when this method masking images than original image resize with mask shape
My requirement is
original image zoom,move,rotate using gesture
after than i want masking
and in masking original image not resize If (Modified or not modified) only put mask shape and other transparent portion crop.
want to mask only color portion from image other portion will be transparent so corp original image with only colored portion of mask image and other portion will be crop not and when original image zoom than that zoomed portion will be covered with mask not original image.
I have one Imageview that contains the Image . And one Mask Shape that contains shape of rabbit.
I have one code that gives the below result.
- (UIImage*)mynewmaskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL,320, 380, 8, 0, colorSpace,(CGBitmapInfo) kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (mainViewContentContext==NULL)
return NULL;
CGFloat ratio = 0;
ratio = 320/ image.size.width;
if(ratio * image.size.height < 380) {
ratio = 380/ image.size.height;
}
CGRect rect1 = {{0, 0}, {320,380}};
CGRect rect2 = {{-((image.size.width*ratio)-320)/2 , -((image.size.height*ratio)-380)/2}, {image.size.width*ratio, image.size.height*ratio}};
// CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image.CGImage);
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;}
The above code gives this result.
But I want the below result (like reverse masking).
How it is possible.Please Help me.
Thanks.
You should look through blendMode. Try smth like this:
[rabbitImage drawInRect:rect
blendMode:kCGBlendModeDestinationOut
alpha:1.0];
I have UITableViewCell with image in the right size.
This is how the cell should look like:
And i have the backgound:
And the image placeholder:
And i want to know if there is a way to crop image with the iOS library?
Yes that possible:
UIImage *imageToCrop = ...;
UIGraphicsBeginImageContext();
CGContextRef context = UIGraphicsGetCurrentContext();
[imageToCrop drawAtPoint:CGPointZero];
CGContextAddEllipseInRect(context, CGRectMake(0 ,0, imageToCrop.size.width, imageToCrop.size.height);
CGContextClip(context);
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
You can use CoreGraphics to add mask or clip with path. Mask is image with alpha channel which determines what part of image show. Below example how clip with image mask:
- (UIImage *)croppedImage:(UIImage *)sourceImage
{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask(context, CGRectMake(0, 0, width, height), [UIImage imageNamed:#"mask"].CGImage);
[sourceImage drawInRect:CGRectMake(0, 0, width, height)];
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
Then you can write cell.picture = [self croppedImage:sourceImage];
You can use image masking technique to crop this image
Please have a look at this link
https://developer.apple.com/library/mac/documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_images/dq_images.html#//apple_ref/doc/uid/TP30001066-CH212-CJBHIJEB
I have written some code that may help you out
#interface ImageRenderer : NSObject {
UIImage *image_;
}
#property (nonatomic, retain) UIImage * image;
- (void)cropImageinRect:(CGRect)rect;
- (void)maskImageWithMask:(UIImage *)maskImage;
- (void)imageWithAlpha;
#end
#implementation ImageRenderer
#synthesize image = image_;
- (void)cropImageinRect:(CGRect)rect {
CGImageRef imageRef = CGImageCreateWithImageInRect(image_.CGImage, rect);
image_ = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
}
- (void)maskImageWithMask:(UIImage *)maskImage {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
if (mainViewContentContext == NULL){
return;
}
CGFloat ratio = 0;
ratio = maskImage.size.width/ image_.size.width;
if(ratio * image_.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ image_.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((image_.size.width*ratio)-maskImage.size.width)/2 , -((image_.size.height*ratio)-maskImage.size.height)/2}, {image_.size.width*ratio, image_.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, image_.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
image_ = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
}
- (void)imageWithAlpha {
CGImageRef imageRef = image_.CGImage;
CGFloat width = CGImageGetWidth(imageRef);
CGFloat height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGImageRef resultImageRef = CGBitmapContextCreateImage(context);
image_ = [UIImage imageWithCGImage:resultImageRef scale:image_.scale orientation:image_.imageOrientation];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
CGImageRelease(resultImageRef);
}
#end
In this code you can crop the image out of a bigger one and then you can use a mask image to get your work done.