3

I'm using this code to resize an image taken with the camera. I reduce it proportionally to a thumbnail, but then I'd like to crop it into a 60x60 square format. I tried incorporating:

CGImageRef imageRef = CGImageCreateWithImageInRect(CGImage, rect); 

but I didn't manage to get it working correctly.How would I do this using Core Graphics?

- (UIImage *) resizeCapturedImage:(UIImage *) img toWidth:(float) w{

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(NULL,w,w, 8, 0, colorspace,kCGImageAlphaPremultipliedFirst);

    CGContextDrawImage(ctx, CGRectMake(0, 0, w,img.size.width*w/img.size.height), img.CGImage);
    CGImageRef thumb = CGBitmapContextCreateImage(ctx);
    UIImage *final = [UIImage imageWithCGImage:thumb scale:1.0 orientation:UIImageOrientationRight];

    return final;
}

2 Answers 2

13

Here i put logic of both Crop and resize image, use it as per your requirement.

For Get Cropped Image:

UIImage *croppedImg = nil;
CGRect cropRect = CGRectMake(AS YOu Need); // set frame as you need
croppedImg = [self croppIngimageByImageName:self.imageView.image toRect:cropRect];

The following method that return UIImage (as You want size of image)

- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect
    {
        //CGRect CropRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height+15);

        CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
        UIImage *cropped = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);

        return cropped;
    }

Here you get Croped Image that return by above method;

OR RESIZING

And also use following method with specific hight and width of image for Resizing:

+ (UIImage*)resizeImage:(UIImage*)image withWidth:(CGFloat)width withHeight:(CGFloat)height
{
    CGSize newSize = CGSizeMake(width, height);
    CGFloat widthRatio = newSize.width/image.size.width;
    CGFloat heightRatio = newSize.height/image.size.height;

    if(widthRatio > heightRatio)
    {
        newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio);
    }
    else
    {
        newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio);
    }


    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

This method return NewImage, with specific size that you want.

7
  • Use CGFloat, not float or int.
    – Guy Kogus
    Commented Oct 14, 2013 at 12:58
  • @GuyKogus - Thanks .. can you explain reason for it ?? because i don't get you.. and also i used this logic in my projects and it working well. thanks :)
    – iPatel
    Commented Oct 14, 2013 at 13:01
  • There's quite a bit to it. The issue is that you're implicitly converting between data types. This can result in unpredictable values, e.g. when you have a float of 3.5 converting to an int, the result may be a 4 if it rounds, but more likely it will convert it to 3 as it truncates. You want to be as consistent as possible with the data types you use, and if you have to convert then do so explicitly and for good reasons. Do you mind if I edit your answer to show what it should be?
    – Guy Kogus
    Commented Oct 14, 2013 at 13:06
  • Another example of a potential problem is losing values. If you have something like a int, which can store a value of +/-65535 and convert it to a short, which can only store values of +/-32767, you will lose the high values.
    – Guy Kogus
    Commented Oct 14, 2013 at 13:10
  • 1
    oPsss.. sory for that :(
    – iPatel
    Commented Oct 14, 2013 at 13:12
4

Just wanted to point out that for performance it is better to crop the image first and then resize the cropped portion than to resize the entire image and then crop it. Especially for larger images.

7
  • Have you tested this that cropping before resizing takes less memory than the other way around? I just tested with the instruments and every time resizing before cropping consumes about 20% less memory (2448, 3264)
    – Islam
    Commented Nov 23, 2015 at 19:02
  • If you are using CIImage on iOS or something similar then it may be doing some optimizations under the hood like stacking the operations. Conceptually it takes longer to resize a 2048 X 1024 pixel image then say 320 X 240 Commented Nov 23, 2015 at 19:10
  • I'm using AVCam example and taking a picture and trying to create a square image (e.g. 640x640 from 2448x3264). When I try to crop to 2448x2448 then resize to 640x640 it's taking about 65Mb, when I resize then crop it's taking about 53Mb.
    – Islam
    Commented Nov 23, 2015 at 19:15
  • I was talking about performance not memory for your specific case you may not see the performance benefit because you are resizing from a very large image to another very large image Commented Nov 23, 2015 at 19:31
  • Do you know of a best way to do both of those actions at once maybe?
    – Islam
    Commented Nov 23, 2015 at 19:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.