I'm using this function to crop an image and when I use it, it doesn't release memory, I tried not using it and the memory works fine.I can't seem to find the problem with it.Please help
- (void) processImage:(UIImage *)image {
haveImage = YES;
UIGraphicsBeginImageContext(image.size);
[image drawInRect: CGRectMake(0, 0, image.size.width, image.size.height)];
__weak UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect cropRect = CGRectMake(0, 0, image.size.width, image.size.height - ((image.size.height - image.size.width)/2));
CGImageRef imageRef = CGImageCreateWithImageInRect([smallImage CGImage], cropRect);
__weak UIImage *corteSuperior =[UIImage imageWithCGImage:imageRef];
cropRect = CGRectMake(0, ((image.size.height - image.size.width)/2), corteSuperior.size.width, corteSuperior.size.height - ((image.size.height - image.size.width)/2));
imageRef = CGImageCreateWithImageInRect([corteSuperior CGImage], cropRect);
self.imagenCamara.image = [UIImage imageWithCGImage:imageRef];
smallImage = nil;
imageRef = nil;
corteSuperior = nil;
UIGraphicsEndImageContext();
CGImageRelease(imageRef);
}
You have to call CGImageRelease call for each CGImageCreateWithImageInRect call. You're never releasing the first occurrence. Before you assign imageRef the second time, release the first imageRef.
Also, at the end, make sure you perform the CGImageRelease before you nil the imageRef pointer. By setting imageRef to nil, you're losing your reference to the imageRef, and thus the CGImageRelease will be unable to release anything.
Related
- (UIImage *)createThumbnailImage:(UIImage *)image withSize:(CGSize)size {
CGRect imageRect = CGRectMake(0.0, 0.0, size.width, size.height);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height));
CGContextSetInterpolationQuality(context, 0.8);
[image drawInRect:imageRect blendMode:kCGBlendModeNormal alpha:1];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thumbnail;
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *inputImage = [UIImage imageNamed:#"dog.jpg"];
UIImage *image = [self createThumbnailImage:inputImage withSize:CGSizeMake(640.0, 480.0)]
}
I got a thumbnail image(640 * 480) by code above. And some odd problem confused me.
When I sent a jpg (10000 * 10000) to the method,it worked well.
But when I sent a png with the same size, the app would crash.
I tried to find some documents about the difference between jpg and png, but it made no sense.
Does anyone have any idea about this bug?
-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
CGImageRelease(subImage);
return croppedImage;
}
can you please check if this solve your problem
Been trying to fix this problem all day to no avail.
Pretty much, I'm taking a screenshot of the view, then trying to crop out the first 50px and a footer. Problem is that when I do this, the result is a little blowed up, and quality is lost. Here's what I wrote, which I think conforms to retina.
-(UIImage *)takeSnapShotAndReturn{
//Take screenshot of whole view
if([[UIScreen mainScreen] respondsToSelector:#selector(scale)]){
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,NO,[UIScreen mainScreen].scale);
}
else{
UIGraphicsBeginImageContext(self.view.window.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
combinedImage = [self cropOutArea:image withRectangle:CGRectMake(0, 50, 320, 467)];
UIImageWriteToSavedPhotosAlbum(combinedImage, nil, nil, nil);
UIGraphicsEndImageContext();
return image;
}
-(UIImage *)cropOutArea:(UIImage*)image withRectangle:(CGRect)rectangle{
if(image.scale > 1){
rectangle = CGRectMake(rectangle.origin.x * image.scale,
rectangle.origin.y * image.scale,
rectangle.size.width * image.scale,
rectangle.size.height * image.scale);
}
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, rectangle);
UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
CGImageRelease(imageRef);
return result;
}
I find cropping extremely confusing!
I'm not sure EXACTLY what you're trying to do, but this may be it .....
-(UIImage *)simplishTopCropAndTo640:(UIImage *)fromImage
// moderately optimised!
{
float shortDimension = fminf(fromImage.size.width, fromImage.size.height);
// 1.use CGImageCreateWithImageInRect to take only the top square...
// 2. use drawInRect (or CGContextDrawImage, same) to scale...
CGRect topSquareOfOriginalRect =
CGRectMake(0,0, shortDimension,shortDimension);
// NOT fromImage.size.width,fromImage.size.width);
CGImageRef topSquareIR = CGImageCreateWithImageInRect(
fromImage.CGImage, topSquareOfOriginalRect);
CGSize size = CGSizeMake( 640,640 );
CGRect sized = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
CGContextRef cc = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(cc, kCGInterpolationLow);
CGContextTranslateCTM(cc, 0, size.height);
CGContextScaleCTM(cc, 1.0, -1.0);
CGContextDrawImage(cc, sized, topSquareIR );
// arguably, those three lines more simply...
//[[UIImage imageWithCGImage:topSquareIR] drawInRect:sized];
CGImageRelease(topSquareIR);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
result =
[UIImage imageWithCGImage:result.CGImage
scale:result.scale
orientation: fromImage.imageOrientation];
//consider...something like...
//[UIImage imageWithCGImage:cgimg
// scale:3 orientation:fromImage.imageOrientation];
return result;
}
Consider also this valuable category .....
-(UIImage *)ordinaryCrop:(CGRect)toRect
{
// crops any image, to any rect. you can't beat that
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], toRect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
Finally don't forget this if you're using the camera "the most useful code in the universe!" iOS UIImagePickerController result image orientation after upload
Hope it helps somehow
Try setting this BOOL property before releasing result in cropOutArea.
result.layer.masksToBounds = YES
Crop image from particular position and set to another view
Final image view
self.finalImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 20, 320, 320)];
if(rectangle_button_preesed_view)
{
self.finalImageView.image =[self croppIngimageByImageName:self.imageView.image toRect:CGRectMake(30, 120, 260, 340)];
}
else
{
self.finalImageView.image =[self croppIngimageByImageName:self.imageView.image toRect:CGRectMake(30, 80, 260, 260)];
}
Cropping image
- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
NSLog(#" cropped size %f %f ",cropped.size.width,cropped.size.height);
return cropped;
}
#implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)cropRect {
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], cropRect);
UIImage *cropedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropedImage;
}
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
// or use the UIImage wherever you like
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);
OR
#implementation UIImage (Crop)
- (UIImage *)crop:(CGRect)rect {
rect = CGRectMake(rect.origin.x*self.scale,
rect.origin.y*self.scale,
rect.size.width*self.scale,
rect.size.height*self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage *result = [UIImage imageWithCGImage:imageRef
scale:self.scale
orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}
#end
Beside CoreGraphics solution, I would also suggest to use CoreImage which support filters for image manipulation. You should look at CICrop filter found in this documentation page.
Note: This filter is supported for iOS 5 or greater.
I currently do not have an exact solution but you can go ahead with a similar thread.
Hope it helps!
So I have a UIImage which I want to crop. I looked and found imageByCroppingToRect method for CIImage. So, I converted the data to CIImage instead of UIImage, crop it using the specified method and then convert the resulting CIImage to UIImage and then display it in a UIImageView.
My code is
NSData *data = [[NSData alloc]initWithData:[def objectForKey:#"imageData"]];
//UIImage *normalImage = [[UIImage alloc]initWithData:data];
CIImage *originalImage = [CIImage imageWithData:data];
[originalImage imageByCroppingToRect:CGRectMake(10, 72, 300, 300)];
self.imageView.image = [UIImage imageWithCIImage:originalImage];
The problem is the image gets rotated by 90 degrees and I am not sure if it is being cropped. This image is captured using the device's camera. I use AVFoundation to access the camera. My session preset is AVCaptureSessionPresetPhoto. I think this is why I get the zooming.
CGRect rect = CGRectMake(10, 72, 300, 300);
CGImageRef imref = CGImageCreateWithImageInRect([yourOriginalImage CGImage], rect);
UIImage *newSubImage = [UIImage imageWithCGImage:imref];
try this. may help u.
EDIT:
Firstly fix your image orientation:
refs : https://github.com/j3r3miah/mapmatic-ios/blob/master/Mapmatic/UIImage+FixOrientation.m
then use above code to crop the Image to Specified Rect.
Not really an answer to your question, but an answer to your problem
https://github.com/mbcharbonneau/UIImage-Categories
especially this file : https://github.com/mbcharbonneau/UIImage-Categories/blob/master/UIImage%2BResize.m
- (UIImage *)croppedImage:(CGRect)bounds {
CGFloat scale = MAX(self.scale, 1.0f);
CGRect scaledBounds = CGRectMake(bounds.origin.x * scale, bounds.origin.y * scale, bounds.size.width * scale, bounds.size.height * scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], scaledBounds);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
return croppedImage;
}
you will find there all you need to crop your image
I'm doing a screenshot of a portion of the screen by this code :
-(UIImage *) takePic {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,YES, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
CGRect rect = CGRectMake(20,238 ,600 , 532);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return img;
}
This works well, but it takes too much time, since I'm taking the imageContext of the entire Self.View.bounds first then retake a small CGRect from.
How can I improve my code to get the method running faster? thanks.