How to crop square area of an image in iOS? - ios

I need to crop and straighten a rotated square area from an UIImage and then store to a new UIImage object. The following picture will make you understand what I want to do. With the locations of point A, B and the width of the square known, how to crop the area out and make it straight? Could you please show me the example code to accomplish this in detail?
Swift or Objective-C is OK. Thanks in advance.

Use This Code For Cropping the Image
// Create the image from a png file
UIImage *image = [UIImage imageNamed:#"myImage.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
// Get size of current image
CGSize size = [image size];
// Frame location in view to show original image
[imageView setFrame:CGRectMake(0, 0, size.width, size.height)];
[[self view] addSubview:imageView];
// Create rectangle that represents a cropped image
// from the middle of the existing image
CGRect rect = CGRectMake(size.width / 4, size.height / 4 ,
(size.width / 2), (size.height / 2));
// Create bitmap image from original image data,
// using rectangle to specify desired crop area
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(0, 200, (size.width / 2), (size.height / 2))];
[[self view] addSubview:imageView];

Related

CGImageCreateWithImageInRect not cropping at correct position

I have a scenario in my app where I take a screenshot of the video using
[myMovieController requestThumbnailImagesAtTimes:#[#(myMovieController.currentPlaybackTime)] timeOption:MPMovieTimeOptionExact];
which just works fine. Then I have to crop the image with touched location on the video. I have added gesture recognizer of myMovieController. I get the touch location from the gesture Recognizer.
then I use following code to take the screen shot
CGRect cropRect = tapCircleView.frame;
cropRect = CGRectMake(touchPoint.x * image.scale,
touchPoint.y * image.scale,
cropRect.size.width * image.scale,
cropRect.size.height * image.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropRect) ;
UIImage* cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
[self showImage:cropped];
where cropRect width and height is 150.
But crop result is not with correct x and y. And also resulting image is very pixilated.
I have tried every solution but it's not working.
What is it that I am missing?
Thanks.
The image size which captures screenshot is not same as device size on which application is running.
So instead of using same image, change size of image using following code :
CGRect rect = CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
UIGraphicsBeginImageContext( rect.size );
[image drawInRect:rect];
UIImage *picture1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imageData = UIImagePNGRepresentation(picture1);
UIImage *img=[UIImage imageWithData:imageData];
And now just use this image wherever you want !!
Cheers.

Blur a specific portion of a UIImage

I have a UIImageView and I want to blur only the bottom portion of the image.
Can someone help me with this ?
I have used UIImage + ImageEffects category to blur the image completely. How can I do it for a specific portion only ?
Split your UIImage into two UIImages. Blur the one you want, leave the other one unaffected. The following splits the image exactly at the center, adjust the rects in the CGImageCreateWithImageInRect calls if you want to move the blurred portion.
UIImage *image = [UIImage imageNamed:#"yourImage.png"];
CGFloat halfImageHeight = image.size.height / 2.f;
CGImageRef topImgRef = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, 0, image.size.width, halfImageHeight));
UIImage *topImage = [UIImage imageWithCGImage:topImgRef];
CGImageRelease(topImgRef);
CGImageRef bottomImgRef = CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, halfImageHeight, image.size.width, halfImageHeight));
UIImage *bottomImage = [UIImage imageWithCGImage:bottomImgRef];
CGImageRelease(bottomImgRef);
// Add blur effects to bottomImage

How to cut an image into irregular shapes using objective c

Thanks to everyone. I have got solution for cutting an image into irregular shapes in java. But now i want to achieved this in iOS.
Here is my requirement:
I am using fingers to select particular part by touch and draw on an image , after completing drawing, i want to draw that part of the image. I am able to draw using touches, but how can i cut that particular part?
i know cutting an image into rectangular shape and circle but not into a particular shape.
If any one know please help me.
Draw a closed CGPath and turn it into an Image Mask. If I had more experience I'd give more details, but I've only done the graphs in a weather app. A guide should help.
Bellow is the code for corp image with selected rectangle area. But you can customized your selected area with CGPath and then corp the image.
-(IBAction) cropImage:(id) sender{
// Create rectangle that represents a cropped image
// from the middle of the existing image
float xCo,yCo;
float width=bottomCornerPoint.x-topCornerPoint.x;
float height=bottomCornerPoint.y-topCornerPoint.y;
if(width<0)
width=-width;
if(height<0)
height=-height;
if(topCornerPoint.x <bottomCornerPoint.x){
xCo=topCornerPoint.x;
}else{
xCo=bottomCornerPoint.x;
}
if(topCornerPoint.y <bottomCornerPoint.y){
yCo=topCornerPoint.y;
}else{
yCo=bottomCornerPoint.y;
}
CGRect rect = CGRectMake(xCo,yCo,width,height);
// Create bitmap image from original image data,
// using rectangle to specify desired crop area
UIImage *image = [UIImage imageNamed:#"abc.png"];
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// Create and show the new image from bitmap data
imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(110, 600, width, height)];
imageView.image=img;
[[self view] addSubview:imageView];
[imageView release];
}
CGSize newSize = CGSizeMake(backGroundImageView.frame.size.width, backGroundImageView.frame.size.height);
UIGraphicsBeginImageContext(newSize);
[<Drawing Imageview> drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
[backGroundImageView.image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeSourceIn alpha:1.0];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Cropping and scaling a UIImage properly

I'm trying to crop a image into a square shape, and then scale it to a size 200x200. Here's the code I use, but it's not really working for me. The image I get is sometimes in a different orientation, or isn't cropped from the center, or is wider than it should be.
float scale = _avatar.image.scale;
UIImageOrientation orientation = _avatar.image.imageOrientation;
if(_avatar.image.size.width < _avatar.image.size.height){ // avatar is a UIImageView
float startingY = (_avatar.image.size.height-_avatar.image.size.width)/2; // image is taller, determine the origin of the width-sized square, which will be the new image
CGImageRef imageRef = CGImageCreateWithImageInRect([_avatar.image CGImage], CGRectMake(0, startingY, _avatar.image.size.width, _avatar.image.size.width));
_avatar.image = [UIImage imageWithCGImage:imageRef scale:scale orientation:orientation];
CGImageRelease(imageRef);
} else {
float startingX = (_avatar.image.size.width-_avatar.image.size.height)/2; // image is wider, determine the origin of the height-sized square, which will be the new image
CGImageRef imageRef = CGImageCreateWithImageInRect([_avatar.image CGImage], CGRectMake(startingX, 0, _avatar.image.size.height, _avatar.image.size.height));
_avatar.image = [UIImage imageWithCGImage:imageRef scale:scale orientation:orientation];
CGImageRelease(imageRef);
}
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), YES, 0.0);
[_avatar.image drawInRect:CGRectMake(0, 0, 200, 200)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
How it must be done to achieve the correct result?
I would suggest you to use this category for UIImage posted on github. They are also really simple classes and you can also use them to learn what is under the hood.
The UIImage has done all the coordinate and orientation tricks for you. So you should not use the width and height from an UIImage object to caculate the square's coordinate. You can take advantages of the UIKit to crop an image.
CGFloat startingX = 0;
CGFloat startingY = 0;
CGFloat squareWidth;
if(_avatar.image.size.width < _avatar.image.size.height){ // avatar is a UIImageView
startingY = (_avatar.image.size.height-_avatar.image.size.width)/2; // image is taller, determine the origin of the width-sized square, which will be the new image
squareWidth = _avatar.image.size.width;
} else {
startingX = (_avatar.image.size.width-_avatar.image.size.height)/2; // image is wider, determine the origin of the height-sized square, which will be the new image
squareWidth = _avatar.image.size.height;
}
UIGraphicsBeginImageContextWithOptions(CGSizeMake(squareWidth, squareWidth), YES, 0.0);
[_avatar.image drawAtPoint:CGPointMake(-startingX, -startingY)]; // Make an offset to draw part of the image
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), YES, 0.0);
[croppedImage drawInRect:CGRectMake(0, 0, 200, 200)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Cropping and placing image to achieve battery level effect

I am trying to achieve the battery level effect by drawing on a plain battery image another cropped image based on current battery level.
At the moment I am able to change the colour of the empty battery image but I don't know how to crop, the new one, and place it on top of the original.
I've found some useful links on how to crop but, every single of them, is cropping from top-left corner of the image. I would like to have as a starting point the bottom-left and set the height according to current level.
In addition, it is possible to combine or place the cropped image on top of the original?
Here is my original image.
...and what I am trying to achieve
At the moment I am trying this code,
int width = emptyBm.size.width;
int height = fullBm.size.height * level / 100;
UIImage *image = [UIImage imageNamed:#"battery_icon"];
UIImage *image2 = [UIImage imageNamed:#"battery_icon_full"];
CGRect rect = CGRectMake(0, image.size.height-height, width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([image2 CGImage], rect);
CGImageRef actualMask = CGImageMaskCreate(CGImageGetWidth([image CGImage]),
CGImageGetHeight([image CGImage]),
CGImageGetBitsPerComponent([image CGImage]),
CGImageGetBitsPerPixel([image CGImage]),
CGImageGetBytesPerRow([image CGImage]),
CGImageGetDataProvider([image CGImage]), NULL, false);
CGImageRef masked = CGImageCreateWithMask(imageRef, actualMask);
batteryBackground.image = [UIImage imageWithCGImage:masked];
However, because I am using CGImageCreateWithImageInRect the cropped part is stretched
Use the gray battery image as mask. Create a green rectangle and apply the mask you created. Here is a link to iOS masking: link
EDIT:
I hope this works (not tested):
int width = emptyBm.size.width;
int height = fullBm.size.height * level / 100;
UIImage *image = [UIImage imageNamed:#"battery_icon"];
UIImage *image2 = [UIImage imageNamed:#"battery_icon_full"];
// For clarity, just pretend the mask method I gave link to you is defined in your class.
UIImage *maskedImage = [self maskImage:image2 withMask:image];
// I assume the two imageviews are already connected to outlets.
self.backgroundImageView = [[UIImageView alloc] initWithImage:image];
self.foregroundImageView = [[UIImageView alloc] initWithImage:maskedImage];
// Make it's image stick to bottom so it won't stretch.
self.foregroundImageView.contentMode = UIViewContentModeBottom;
// Then calculate the frame again to reflect changes of battery status.
CGRect rect = self.backgroundImageView.frame;
rect.size.height = height;
// Push the masked imageview a to bottom as amount of missing battery height.
rect.origin.y = rect.origin.y + self.backgroundImageView.frame.size.height - height;
self.foregroundImageView.frame = rect;

Resources