When attempting to perform a center crop of an UIImage, I get the following results (left is the original image at 640*1136
, and the right is the cropped image fitted to a square UIImageView
at 320*320
):
turns to:
I have tinkered quite a bit with the ratio element so that it could correctly detect the amount to trim: using the shorter side of of the image, constructing a ratio based on short_side/width_of_desired_rect
, but it does not appear to be working in this case. Help appreciated!
- (UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//for retina consideration
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Try this:
- (UIImage *)squareImageFromImage:(UIImage *)image scaledToSize:(CGFloat)newSize {
CGAffineTransform scaleTransform;
CGPoint origin;
if (image.size.width > image.size.height) {
CGFloat scaleRatio = newSize / image.size.height;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(-(image.size.width - image.size.height) / 2.0f, 0);
} else {
CGFloat scaleRatio = newSize / image.size.width;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(0, -(image.size.height - image.size.width) / 2.0f);
}
CGSize size = CGSizeMake(newSize, newSize);
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
} else {
UIGraphicsBeginImageContext(size);
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, scaleTransform);
[image drawAtPoint:origin];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Use this code to resize your image
// Returns image resized to the desired CGSize
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Edit: you are basically redrawing here too. If you are reusing the same image over and over, it might be a good idea to call this once and save the result as a file. Load that instead of the original instead in later calls.
Edit 2: Okay so what you want to do is keep the aspect ratio while fitting the image into a square. The above code basically fits the image into a square by resizing it but it does not keep the aspect ratio. A way of also keeping the aspect ratio would be to find the factor by which you shrink the larger of the two dimensions of the image and then shrink the other dimension by the same factor. Let me know if you have trouble with it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With