I've got the following function, previous to iOS 7 & XCode 5 it worked as expected. The function takes an image and a cropSize. The image is the one to be cropped to a specified size, which is defined by CGSize cropSize. The purpose of the function is to crop the image to a certain size and then return the cropped image.
- (UIImage *) cropImage:(UIImage *)originalImage cropSize:(CGSize)cropSize
{
//calculate scale factor to go between cropframe and original image
float SF = originalImage.size.width / cropSize.width;
//find the centre x,y coordinates of image
float centreX = originalImage.size.width / 2;
float centreY = originalImage.size.height / 2;
//calculate crop parameters
float cropX = centreX - ((cropSize.width / 2) * SF);
float cropY = centreY - ((cropSize.height / 2) * SF);
CGRect cropRect = CGRectMake(cropX, cropY, (cropSize.width *SF), (cropSize.height * SF));
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], cropRect);
//keep orientation if landscape
UIImage *newImage;
if (originalImage.size.width > originalImage.size.height || originalImage.size.width == originalImage.size.height) {
newImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:originalImage.imageOrientation];
}
else
{
newImage = [UIImage imageWithCGImage:imageRef];
}
CGImageRelease(imageRef);
//Now want to scale down cropped image!
//want to multiply frames by 2 to get retina resolution
CGRect scaledImgRect = CGRectMake(0, 0, (cropSize.width * 2), (cropSize.height * 2));
UIGraphicsBeginImageContextWithOptions(scaledImgRect.size, NO, [UIScreen mainScreen].scale);
[newImage drawInRect:scaledImgRect];
UIImage *scaledNewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledNewImage;
}
The problem is that it all works fine in with a UIImage that is passed in that is in landscape orientation, the image is cropped as expected, however if the image passed in was taken in portrait, then the resulting image (the cropped result in scaledNewImage) is rotated 90 degrees on its side, which I don't want.
It is as if the portrait image is being worked on as if it's in landscape - and so the function cropped what should be a portrait orientated image in landscape instead of portrait.
This isn't so apparent if the crop area is square, however if the area to be cropped is a landscape rectangle then it's cropping it along the length of the portrait rather than the width. Hope I'm making sense!
This issue didn't occur prior to iOS 7 & XCode 5.. so I'm not sure exactly what's changed. Any help appreciated, thanks.
Solved this issue with the help of an answer here: https://stackoverflow.com/a/14712184/521653
- (UIImage *) cropImage:(UIImage *)originalImage cropSize:(CGSize)cropSize
{
NSLog(@"original image orientation:%d",originalImage.imageOrientation);
//calculate scale factor to go between cropframe and original image
float SF = originalImage.size.width / cropSize.width;
//find the centre x,y coordinates of image
float centreX = originalImage.size.width / 2;
float centreY = originalImage.size.height / 2;
//calculate crop parameters
float cropX = centreX - ((cropSize.width / 2) * SF);
float cropY = centreY - ((cropSize.height / 2) * SF);
CGRect cropRect = CGRectMake(cropX, cropY, (cropSize.width *SF), (cropSize.height * SF));
CGAffineTransform rectTransform;
switch (originalImage.imageOrientation)
{
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(M_PI_2), 0, -originalImage.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(-M_PI_2), -originalImage.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(-M_PI), -originalImage.size.width, -originalImage.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};
rectTransform = CGAffineTransformScale(rectTransform, originalImage.scale, originalImage.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], CGRectApplyAffineTransform(cropRect, rectTransform));
UIImage *result = [UIImage imageWithCGImage:imageRef scale:originalImage.scale orientation:originalImage.imageOrientation];
CGImageRelease(imageRef);
//return result;
//Now want to scale down cropped image!
//want to multiply frames by 2 to get retina resolution
CGRect scaledImgRect = CGRectMake(0, 0, (cropSize.width * 2), (cropSize.height * 2));
UIGraphicsBeginImageContextWithOptions(scaledImgRect.size, NO, [UIScreen mainScreen].scale);
[result drawInRect:scaledImgRect];
UIImage *scaledNewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledNewImage;
}
That's the updated method there. I implemented the code from the answer linked into my method and it solves the issues. Strange that I didn't have these before iOS 7!
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