Reputation: 5026
I've got some code that resizes an image so I can get a scaled chunk of the center of the image - I use this to take a UIImage
and return a small, square representation of an image, similar to what's seen in the album view of the Photos app. (I know I could use a UIImageView
and adjust the crop mode to achieve the same results, but these images are sometimes displayed in UIWebViews
).
I've started to notice some crashes in this code and I'm a bit stumped. I've got two different theories and I'm wondering if either is on-base.
Theory 1) I achieve the cropping by drawing into an offscreen image context of my target size. Since I want the center portion of the image, I set the CGRect
argument passed to drawInRect
to something that's larger than the bounds of my image context. I was hoping this was Kosher, but am I instead attempting to draw over other memory that I shouldn't be touching?
Theory 2) I'm doing all of this in a background thread. I know there are portions of UIKit that are restricted to the main thread. I was assuming / hoping that drawing to an offscreen view wasn't one of these. Am I wrong?
(Oh, how I miss NSImage's drawInRect:fromRect:operation:fraction:
method.)
Upvotes: 220
Views: 188226
Reputation: 21
For Swift 5 I used next solution (I was needed centered cropped image)
public extension UIImage {
func cropped(rect: CGRect) -> UIImage? {
if let image = self.cgImage?.cropping(to: rect) {
return UIImage(cgImage: image, scale:self.scale, orientation:self.imageOrientation)
}
return nil
}
}
And somewhere in your code you have some "image" as UIImage:
let baseSize = image.size
let delta = abs(baseSize.height - baseSize.width)/2.0
let croppedFrame = baseSize.height > baseSize.width ? CGRect(x: 0, y: delta, width: baseSize.width, height: baseSize.width) :
CGRect(x: delta, y: 0, width: baseSize.height, height: baseSize.height)
guard let croppedImage = image.cropped(rect: croppedFrame) else {
return
}
Upvotes: 0
Reputation: 1418
Swift 5.0 update
public extension UIImage {
func cropped(rect: CGRect) -> UIImage? {
if let image = self.cgImage!.cropping(to: rect) {
return UIImage(cgImage: image)
} else if let image = (self.ciImage)?.cropped(to: rect) {
return UIImage(ciImage: image)
}
return nil
}
}
Upvotes: 0
Reputation: 7760
Swift 5:
extension UIImage {
func cropped(rect: CGRect) -> UIImage? {
guard let cgImage = cgImage else { return nil }
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
let context = UIGraphicsGetCurrentContext()
context?.translateBy(x: 0.0, y: self.size.height)
context?.scaleBy(x: 1.0, y: -1.0)
context?.draw(cgImage, in: CGRect(x: rect.minX, y: rect.minY, width: self.size.width, height: self.size.height), byTiling: false)
let croppedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return croppedImage
}
}
Upvotes: 1
Reputation: 2211
Below code snippet might help.
import UIKit
extension UIImage {
func cropImage(toRect rect: CGRect) -> UIImage? {
if let imageRef = self.cgImage?.cropping(to: rect) {
return UIImage(cgImage: imageRef)
}
return nil
}
}
Upvotes: 5
Reputation: 2096
Swift version of awolf
's answer, which worked for me:
public extension UIImage {
func croppedImage(inRect rect: CGRect) -> UIImage {
let rad: (Double) -> CGFloat = { deg in
return CGFloat(deg / 180.0 * .pi)
}
var rectTransform: CGAffineTransform
switch imageOrientation {
case .left:
let rotation = CGAffineTransform(rotationAngle: rad(90))
rectTransform = rotation.translatedBy(x: 0, y: -size.height)
case .right:
let rotation = CGAffineTransform(rotationAngle: rad(-90))
rectTransform = rotation.translatedBy(x: -size.width, y: 0)
case .down:
let rotation = CGAffineTransform(rotationAngle: rad(-180))
rectTransform = rotation.translatedBy(x: -size.width, y: -size.height)
default:
rectTransform = .identity
}
rectTransform = rectTransform.scaledBy(x: scale, y: scale)
let transformedRect = rect.applying(rectTransform)
let imageRef = cgImage!.cropping(to: transformedRect)!
let result = UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
return result
}
}
Upvotes: 29
Reputation: 2036
Follow Answer of @Arne. I Just fixing to Category function. put it in Category of UIImage.
-(UIImage*)cropImage:(CGRect)rect{
UIGraphicsBeginImageContextWithOptions(rect.size, false, [self scale]);
[self drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];
UIImage* cropped_image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cropped_image;
}
Upvotes: 1
Reputation: 1123
Here's an updated Swift 3 version based on Noodles answer
func cropping(to rect: CGRect) -> UIImage? {
if let cgCrop = cgImage?.cropping(to: rect) {
return UIImage(cgImage: cgCrop)
}
else if let ciCrop = ciImage?.cropping(to: rect) {
return UIImage(ciImage: ciCrop)
}
return nil
}
Upvotes: 1
Reputation: 77904
func cropImage(imageToCrop:UIImage, toRect rect:CGRect) -> UIImage{
let imageRef:CGImage = imageToCrop.cgImage!.cropping(to: rect)!
let cropped:UIImage = UIImage(cgImage:imageRef)
return cropped
}
let imageTop:UIImage = UIImage(named:"one.jpg")! // add validation
with help of this bridge function CGRectMake
-> CGRect
(credits to this answer answered by @rob mayoff
):
func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
return CGRect(x: x, y: y, width: width, height: height)
}
The usage is:
if var image:UIImage = UIImage(named:"one.jpg"){
let croppedImage = cropImage(imageToCrop: image, toRect: CGRectMake(
image.size.width/4,
0,
image.size.width/2,
image.size.height)
)
}
Output:
Upvotes: 64
Reputation: 52161
extension UIImage {
func crop(rect: CGRect) -> UIImage? {
var scaledRect = rect
scaledRect.origin.x *= scale
scaledRect.origin.y *= scale
scaledRect.size.width *= scale
scaledRect.size.height *= scale
guard let imageRef: CGImage = cgImage?.cropping(to: scaledRect) else {
return nil
}
return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
}
}
Upvotes: 11
Reputation: 1
Look at https://github.com/vvbogdan/BVCropPhoto
- (UIImage *)croppedImage { CGFloat scale = self.sourceImage.size.width / self.scrollView.contentSize.width; UIImage *finalImage = nil; CGRect targetFrame = CGRectMake((self.scrollView.contentInset.left + self.scrollView.contentOffset.x) * scale, (self.scrollView.contentInset.top + self.scrollView.contentOffset.y) * scale, self.cropSize.width * scale, self.cropSize.height * scale); CGImageRef contextImage = CGImageCreateWithImageInRect([[self imageWithRotation:self.sourceImage] CGImage], targetFrame); if (contextImage != NULL) { finalImage = [UIImage imageWithCGImage:contextImage scale:self.sourceImage.scale orientation:UIImageOrientationUp]; CGImageRelease(contextImage); } return finalImage; } - (UIImage *)imageWithRotation:(UIImage *)image { if (image.imageOrientation == UIImageOrientationUp) return image; CGAffineTransform transform = CGAffineTransformIdentity; switch (image.imageOrientation) { case UIImageOrientationDown: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0); transform = CGAffineTransformRotate(transform, M_PI_2); break; case UIImageOrientationRight: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, 0, image.size.height); transform = CGAffineTransformRotate(transform, -M_PI_2); break; case UIImageOrientationUp: case UIImageOrientationUpMirrored: break; } switch (image.imageOrientation) { case UIImageOrientationUpMirrored: case UIImageOrientationDownMirrored: transform = CGAffineTransformTranslate(transform, image.size.width, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationLeftMirrored: case UIImageOrientationRightMirrored: transform = CGAffineTransformTranslate(transform, image.size.height, 0); transform = CGAffineTransformScale(transform, -1, 1); break; case UIImageOrientationUp: case UIImageOrientationDown: case UIImageOrientationLeft: case UIImageOrientationRight: break; } // Now we draw the underlying CGImage into a new context, applying the transform // calculated above. CGContextRef ctx = CGBitmapContextCreate(NULL, image.size.width, image.size.height, CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), CGImageGetBitmapInfo(image.CGImage)); CGContextConcatCTM(ctx, transform); switch (image.imageOrientation) { case UIImageOrientationLeft: case UIImageOrientationLeftMirrored: case UIImageOrientationRight: case UIImageOrientationRightMirrored: // Grr... CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.height, image.size.width), image.CGImage); break; default: CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage); break; } // And now we just create a new UIImage from the drawing context CGImageRef cgimg = CGBitmapContextCreateImage(ctx); UIImage *img = [UIImage imageWithCGImage:cgimg]; CGContextRelease(ctx); CGImageRelease(cgimg); return img; }
Upvotes: 0
Reputation: 3410
You can make a UIImage category and use it wherever you need. Based on HitScans response and comments bellow it.
@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
You can use it this way:
UIImage *imageToCrop = <yourImageToCrop>;
CGRect cropRect = <areaYouWantToCrop>;
//for example
//CGRectMake(0, 40, 320, 100);
UIImage *croppedImage = [imageToCrop crop:cropRect];
Upvotes: 66
Reputation: 15978
Swift 2.0 Update (CIImage
compatibility)
Expanding off of Maxim's Answer but works if your image is CIImage
based, as well.
public extension UIImage {
func imageByCroppingToRect(rect: CGRect) -> UIImage? {
if let image = CGImageCreateWithImageInRect(self.CGImage, rect) {
return UIImage(CGImage: image)
} else if let image = (self.CIImage)?.imageByCroppingToRect(rect) {
return UIImage(CIImage: image)
}
return nil
}
}
Upvotes: 1
Reputation: 3659
Heads up: all these answers assume a CGImage
-backed image object.
image.CGImage
can return nil, if the UIImage
is backed by a CIImage
, which would be the case if you created this image using a CIFilter
.
In that case, you might have to draw the image in a new context, and return that image (slow).
UIImage* crop(UIImage *image, rect) {
UIGraphicsBeginImageContextWithOptions(rect.size, false, [image scale]);
[image drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];
cropped_image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return cropped_image;
}
Upvotes: 45
Reputation: 21
I use the method below.
-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
CGSize cropSize = rect.size;
CGFloat widthScale =
image.size.width/self.imageViewOriginal.bounds.size.width;
CGFloat heightScale =
image.size.height/self.imageViewOriginal.bounds.size.height;
cropSize = CGSizeMake(rect.size.width*widthScale,
rect.size.height*heightScale);
CGPoint pointCrop = CGPointMake(rect.origin.x*widthScale,
rect.origin.y*heightScale);
rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width,
cropSize.height);
CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
CGImageRelease(subImage);
return croppedImage;
}
Upvotes: 0
Reputation: 21
On iOS9.2SDK ,I use below method to convert frame from UIView to UIImage
-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
CGSize cropSize = rect.size;
CGFloat widthScale = image.size.width/self.imageViewOriginal.bounds.size.width;
CGFloat heightScale = image.size.height/self.imageViewOriginal.bounds.size.height;
cropSize = CGSizeMake(rect.size.width*widthScale,
rect.size.height*heightScale);
CGPoint pointCrop = CGPointMake(rect.origin.x*widthScale,
rect.origin.y*heightScale);
rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, cropSize.height);
CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
CGImageRelease(subImage);
return croppedImage;
}
Upvotes: 1
Reputation: 141
Looks a little bit strange but works great and takes into consideration image orientation:
var image:UIImage = ...
let img = CIImage(image: image)!.imageByCroppingToRect(rect)
image = UIImage(CIImage: img, scale: 1, orientation: image.imageOrientation)
Upvotes: 2
Reputation: 33958
Swift Extension
extension UIImage {
func crop(var rect: CGRect) -> UIImage {
rect.origin.x*=self.scale
rect.origin.y*=self.scale
rect.size.width*=self.scale
rect.size.height*=self.scale
let imageRef = CGImageCreateWithImageInRect(self.CGImage, rect)
let image = UIImage(CGImage: imageRef, scale: self.scale, orientation: self.imageOrientation)!
return image
}
}
Upvotes: 7
Reputation: 15694
Best solution for cropping an UIImage in Swift, in term of precision, pixels scaling ...:
private func squareCropImageToSideLength(let sourceImage: UIImage,
let sideLength: CGFloat) -> UIImage {
// input size comes from image
let inputSize: CGSize = sourceImage.size
// round up side length to avoid fractional output size
let sideLength: CGFloat = ceil(sideLength)
// output size has sideLength for both dimensions
let outputSize: CGSize = CGSizeMake(sideLength, sideLength)
// calculate scale so that smaller dimension fits sideLength
let scale: CGFloat = max(sideLength / inputSize.width,
sideLength / inputSize.height)
// scaling the image with this scale results in this output size
let scaledInputSize: CGSize = CGSizeMake(inputSize.width * scale,
inputSize.height * scale)
// determine point in center of "canvas"
let center: CGPoint = CGPointMake(outputSize.width/2.0,
outputSize.height/2.0)
// calculate drawing rect relative to output Size
let outputRect: CGRect = CGRectMake(center.x - scaledInputSize.width/2.0,
center.y - scaledInputSize.height/2.0,
scaledInputSize.width,
scaledInputSize.height)
// begin a new bitmap context, scale 0 takes display scale
UIGraphicsBeginImageContextWithOptions(outputSize, true, 0)
// optional: set the interpolation quality.
// For this you need to grab the underlying CGContext
let ctx: CGContextRef = UIGraphicsGetCurrentContext()
CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh)
// draw the source image into the calculated rect
sourceImage.drawInRect(outputRect)
// create new image from bitmap context
let outImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
// clean up
UIGraphicsEndImageContext()
// pass back new image
return outImage
}
Instructions used to call this function:
let image: UIImage = UIImage(named: "Image.jpg")!
let squareImage: UIImage = self.squareCropImageToSideLength(image, sideLength: 320)
self.myUIImageView.image = squareImage
Note: the initial source code inspiration written in Objective-C has been found on "Cocoanetics" blog.
Upvotes: 4
Reputation: 157
(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);
//start a new context, with scale factor 0.0 so retina displays get
//high quality image
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;
}
Upvotes: 1
Reputation: 1972
None of the answers here handle all of the scale and rotation issues 100% correctly. Here's a synthesis of everything said so far, up-to-date as of iOS7/8. It's meant to be included as a method in a category on UIImage.
- (UIImage *)croppedImageInRect:(CGRect)rect
{
double (^rad)(double) = ^(double deg) {
return deg / 180.0 * M_PI;
};
CGAffineTransform rectTransform;
switch (self.imageOrientation) {
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -self.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -self.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -self.size.width, -self.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};
rectTransform = CGAffineTransformScale(rectTransform, self.scale, self.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], CGRectApplyAffineTransform(rect, rectTransform));
UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
CGImageRelease(imageRef);
return result;
}
Upvotes: 38
Reputation: 8739
Update 2014-05-28: I wrote this when iOS 3 or so was the hot new thing, I'm certain there are better ways to do this by now, possibly built-in. As many people have mentioned, this method doesn't take rotation into account; read some additional answers and spread some upvote love around to keep the responses to this question helpful for everyone.
Original response:
I'm going to copy/paste my response to the same question elsewhere:
There isn't a simple class method to do this, but there is a function that you can use to get the desired results: CGImageCreateWithImageInRect(CGImageRef, CGRect)
will help you out.
Here's a short example using it:
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
// or use the UIImage wherever you like
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);
Upvotes: 238
Reputation: 2863
I wasn't satisfied with other solutions because they either draw several time (using more power than necessary) or have problems with orientation. Here is what I used for a scaled square croppedImage from a UIImage * image.
CGFloat minimumSide = fminf(image.size.width, image.size.height);
CGFloat finalSquareSize = 600.;
//create new drawing context for right size
CGRect rect = CGRectMake(0, 0, finalSquareSize, finalSquareSize);
CGFloat scalingRatio = 640.0/minimumSide;
UIGraphicsBeginImageContext(rect.size);
//draw
[image drawInRect:CGRectMake((minimumSide - photo.size.width)*scalingRatio/2., (minimumSide - photo.size.height)*scalingRatio/2., photo.size.width*scalingRatio, photo.size.height*scalingRatio)];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Upvotes: 0
Reputation: 5190
Here is my UIImage crop implementation which obeys the imageOrientation property. All orientations were thoroughly tested.
inline double rad(double deg)
{
return deg / 180.0 * M_PI;
}
UIImage* UIImageCrop(UIImage* img, CGRect rect)
{
CGAffineTransform rectTransform;
switch (img.imageOrientation)
{
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};
rectTransform = CGAffineTransformScale(rectTransform, img.scale, img.scale);
CGImageRef imageRef = CGImageCreateWithImageInRect([img CGImage], CGRectApplyAffineTransform(rect, rectTransform));
UIImage *result = [UIImage imageWithCGImage:imageRef scale:img.scale orientation:img.imageOrientation];
CGImageRelease(imageRef);
return result;
}
Upvotes: 49
Reputation: 139
- (UIImage *)getSubImage:(CGRect) rect{
CGImageRef subImageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
CGRect smallBounds = CGRectMake(rect.origin.x, rect.origin.y, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
UIGraphicsBeginImageContext(smallBounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, smallBounds, subImageRef);
UIImage* smallImg = [UIImage imageWithCGImage:subImageRef];
UIGraphicsEndImageContext();
return smallImg;
}
Upvotes: 1
Reputation: 1537
To crop retina images while keeping the same scale and orientation, use the following method in a UIImage category (iOS 4.0 and above):
- (UIImage *)crop:(CGRect)rect {
if (self.scale > 1.0f) {
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;
}
Upvotes: 94
Reputation: 571
CGSize size = [originalImage size];
int padding = 20;
int pictureSize = 300;
int startCroppingPosition = 100;
if (size.height > size.width) {
pictureSize = size.width - (2.0 * padding);
startCroppingPosition = (size.height - pictureSize) / 2.0;
} else {
pictureSize = size.height - (2.0 * padding);
startCroppingPosition = (size.width - pictureSize) / 2.0;
}
// WTF: Don't forget that the CGImageCreateWithImageInRect believes that
// the image is 180 rotated, so x and y are inverted, same for height and width.
CGRect cropRect = CGRectMake(startCroppingPosition, padding, pictureSize, pictureSize);
CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], cropRect);
UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:originalImage.imageOrientation];
[m_photoView setImage:newImage];
CGImageRelease(imageRef);
Most of the responses I've seen only deals with a position of (0, 0) for (x, y). Ok that's one case but I'd like my cropping operation to be centered. What took me a while to figure out is the line following the WTF comment.
Let's take the case of an image captured with a portrait orientation:
Hope it makes sense! If it does not, try different values you'll see that the logic is inverted when it comes to choosing the right x, y, width, and height for your cropRect.
Upvotes: 10