CGImageCreateWithImageInRect not Cropping Right

I use CGImageCreateWithImageInRect to crop a photo. My application has the ability to move / enlarge the user's image until it fills 316 x 316, and then I want it to crop any area outside the field and save the image as UIImage. I determine the origin of the crop by taking the absolute value of the image source x and y, as this returns me to the 0.0 field of the view / containing the image. Below is the code:

CGRect croppedRect = CGRectMake(fabs(widthDistanceToOrigin), fabs(HeightDistanceToOrigin), 316, 316); CGImageRef croppedImageRef = CGImageCreateWithImageInRect(image.CGImage, croppedRect); UIImage *croppedImage = [UIImage imageWithCGImage: croppedImageRef scale: 1 / (imageScale) orientation: image.imageOrientation]; CGImageRelease(croppedImageRef); 

It drives me crazy, I just can't get it to crop the area I want. I have this to scale correctly, but the problem seems to be related to the x and y origin of the rect crop, it is quite a bit from the area that it should take (and sometimes I get strange results).

In addition, it seems that for images taken with the phone’s camera, I have to multiply everything in my plant by 2 so that it is the right size. Very strange.

So, I am wondering if anyone knows how to fix this, or does anyone have a better way to crop (and please keep in mind that I need to crop the area in my photo). Thanks!

+4
source share
3 answers

I found a problem. I tried to capture the crop area before scaling the image. Now I need to figure out how to reduce the image before I do "CGImageCreateWithImageInRect".

0
source

There are so many posts on this topic, all of them have the same exact answer, use: CGImageCreateWithImageInRect but none of them completely solve the problem of missing positioning of what it is trying to crop.

However, only one thread (deeply immersed deep in depth) has an insignificant detail that everyone else lacks ... How to crop a UIImageView into a new UIImage mode in aspect matching mode?

the 'rect' parameter, which is included in CGImageCreateWithImageInRect (image.CGImage, croppedRect) should represent (taken from) UIImage, not UIImageView.

this should solve the problem of positioning gaps in the coordinate system.

  - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { oImage = [info valueForKey:UIImagePickerControllerOriginalImage]; NSLog(@"Original Image size width: %fx height: %f", oImage.size.width, oImage.size.height); // crop image according to what the image picker view is displaying CGRect rect = CGRectMake(0, 40, 960.0f, 960.0f); // note: 960 x 1280 is what natively comes from capturing and image nImage = [BGViewModifiers cropImage:oImage inRect:rect]; // scale image down for display and creating kombie CGSize size = CGSizeMake(320.0f, 320.0f); nImage = [BGViewModifiers imageFromImage:nImage scaledToSize:size]; NSLog(@"New Image size width: %fx height: %f", [nImage size].width, [nImage size].height); } //ref: http://stackoverflow.com/a/25293588/2298002 + (UIImage *)cropImage:(UIImage*)image inRect:(CGRect)rect { double (^rad)(double) = ^(double deg) { return deg / 180.0 * M_PI; }; CGAffineTransform rectTransform; switch (image.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale); CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], CGRectApplyAffineTransform(rect, rectTransform)); UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; CGImageRelease(imageRef); return result; } + (UIImage*)imageFromImage:(UIImage*)image scaledToSize:(CGSize)newSize { UIGraphicsBeginImageContext( newSize ); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 
+4
source

I would like to provide additional information / answer for this based on my own experience.

From a UIImage perspective (and therefore CGImageCreateWithImageInRect: , (0, 0) is in the lower left corner. When determining the cropping square, you can simply calculate the square based on the standard portrait orientation, and then use the method in @greenhouse's answer (here again for clarity and changed to use CGFloat to fix the casting error.

 - (UIImage *)cropImage:(UIImage*)image toRect:(CGRect)rect { CGFloat (^rad)(CGFloat) = ^CGFloat(CGFloat deg) { return deg / 180.0f * (CGFloat) M_PI; }; // determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position CGAffineTransform rectTransform; switch (image.imageOrientation) { case UIImageOrientationLeft: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height); break; case UIImageOrientationRight: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0); break; case UIImageOrientationDown: rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height); break; default: rectTransform = CGAffineTransformIdentity; }; // adjust the transformation scale based on the image scale rectTransform = CGAffineTransformScale(rectTransform, image.scale, image.scale); // apply the transformation to the rect to create a new, shifted rect CGRect transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform); // use the rect to crop the image CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare); // create a new UIImage and set the scale and orientation appropriately UIImage *result = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; // memory cleanup CGImageRelease(imageRef); return result; } 

This code shifts the cropping square so that it is in the correct relative position.

+2
source

Source: https://habr.com/ru/post/1380344/


All Articles