CGImageCreateWithImageInRect 不能正确裁剪
Posted
技术标签:
【中文标题】CGImageCreateWithImageInRect 不能正确裁剪【英文标题】:CGImageCreateWithImageInRect not Cropping Correctly 【发布时间】:2011-11-09 06:57:26 【问题描述】:我正在使用 CGImageCreateWithImageInRect 裁剪照片。我的应用程序让用户移动/放大图像直到它填充 316 x 316 视图,然后我希望它裁剪框外的任何区域并将图像保存为 UIImage。我通过获取 x 和 y 图像视图原点的绝对值来确定裁剪原点,因为这使我回到包含图像视图的视图/框的 0,0。下面是代码:
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);
这让我发疯,我无法让它裁剪我想要的区域。我已经让它正确缩放,但问题似乎出在裁剪矩形的 x 和 y 原点上,它与它应该占用的区域相差很大(有时我会得到奇怪的结果)。
此外,对于用手机相机拍摄的图像,我必须将裁剪矩形中的所有内容乘以 2 才能使其尺寸正确。很奇怪。
所以我想知道,有没有人知道如何解决这个问题,或者有没有人有更好的裁剪方法(请记住,我需要裁剪照片中的一个区域)。谢谢!
【问题讨论】:
请在回答中提供您的解决方案,并在系统允许后接受。 【参考方案1】:关于这个主题的帖子太多了,所有帖子都有相同的确切答案, 利用:CGImageCreateWithImageInRect 但它们都没有完全解决试图裁剪的东西定位错误的问题。
但是,只有一个线程(深埋在里面)有一个其他人都没有的小细节...... How to crop a UIImageView to a new UIImage in 'aspect fit' mode?
传入的'rect'参数 CGImageCreateWithImageInRect(image.CGImage,croppedRect) 需要表示(取自)UIImage,而不是 UIImageView。
这应该可以解决在坐标系上定位不准的问题。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info
oImage = [info valueForKey:UIImagePickerControllerOriginalImage];
NSLog(@"Original Image size width: %f x 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: %f x height: %f", [nImage size].width, [nImage size].height);
//ref: http://***.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;
【讨论】:
【参考方案2】:我想根据自己的经验提供更多信息/答案。
从UIImage
(以及CGImageCreateWithImageInRect:
)的角度来看,(0, 0)
位于左下方。在确定裁剪正方形时,您可以简单地根据标准纵向计算正方形,然后使用@greenhouse 的答案中的方法(为了清楚起见,这里再次发布并更改为使用CGFloat
来修复投射错误。
- (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;
此代码移动裁剪方块,使其处于正确的相对位置。
【讨论】:
非常适合我【参考方案3】:我发现了问题。在缩放图像之前,我试图抓住裁剪区域。现在必须弄清楚如何在我执行“CGImageCreateWithImageInRect”之前缩小图像。
【讨论】:
以上是关于CGImageCreateWithImageInRect 不能正确裁剪的主要内容,如果未能解决你的问题,请参考以下文章