我有一些代码来调整图像的大小,这样我就可以得到图像中心的缩放块-我用这个来获取一个UIImage,并返回一个小的,正方形的图像表示,类似于在照片应用程序的相册视图中看到的。(我知道我可以使用UIImageView和调整裁剪模式来实现相同的结果,但这些图像有时显示在UIWebViews中)。
我已经开始注意到这段代码中的一些崩溃,我有点难住了。我有两种不同的理论,不知道哪一种是正确的。
理论1)我通过绘制到目标尺寸的屏幕外图像上下文来实现裁剪。因为我想要图像的中心部分,所以我将传递给drawwinrect的CGRect参数设置为比图像上下文的边界更大的值。我希望这是符合规定的,但我是不是在试图掩盖其他我不应该触及的记忆?
理论2)我在后台线程中做所有这些。我知道UIKit的某些部分被限制在主线程中。我假设/希望绘制到屏幕外的视图不是其中之一。我错了吗?
(哦,我真怀念NSImage的drawwinrect:fromRect:operation:fraction:方法。)
在iOS9.2SDK上,我使用下面的方法将帧从UIView转换为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;
}
这是我的UIImage作物实现,它遵从imageOrientation属性。所有方向都经过了彻底的测试。
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;
}
更新2014-05-28:我写这篇文章的时候,iOS 3左右还是热门的新事物,我相信现在有更好的方法来做到这一点,可能是内置的。正如很多人提到的,这种方法没有考虑到轮换;阅读一些额外的答案,并散布一些点赞的爱,让这个问题的回答对每个人都有帮助。
最初的反应:
我将把我对相同问题的回答复制/粘贴到其他地方:
没有一个简单的类方法可以做到这一点,但有一个函数可以使用来获得所需的结果:CGImageCreateWithImageInRect(CGImageRef, CGRect)将帮助您解决这个问题。
下面是一个简短的例子:
CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
// or use the UIImage wherever you like
[UIImageView setImage:[UIImage imageWithCGImage:imageRef]];
CGImageRelease(imageRef);
我使用下面的方法。
-(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;
}
你可以创建一个UIImage类别,并在任何你需要的地方使用它。基于HitScans的响应和咆哮的评论。
@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
你可以这样用:
UIImage *imageToCrop = <yourImageToCrop>;
CGRect cropRect = <areaYouWantToCrop>;
//for example
//CGRectMake(0, 40, 320, 100);
UIImage *croppedImage = [imageToCrop crop:cropRect];
- (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;
}