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 repre
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
}
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:
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; }
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)
}
}
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;
}
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;
}