最近做了一个项目,需要把相片放到一个控制器中可以旋转,缩放,并且移动,然后截取固定的区域生成另一张图片。我研究了了底层的UIGraphics框架通过将控制器的view先转换成图片再进行图片截图工作。
1.转换图片
-(UIImage*)convertViewToImage:(UIView*)v{
CGSize s = v.bounds.size;
// 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了
UIGraphicsBeginImageContextWithOptions(s, YES, 1.0);
[v.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
2.截取图片
- (UIImage*)getSubImage:(CGRect)rect
{
UIImage *preSmallImage = [self convertViewToImage:self.view];
CGImageRef subImageRef = CGImageCreateWithImageInRect(preSmallImage.CGImage, rect);
CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));
UIGraphicsBeginImageContext(smallBounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, smallBounds, subImageRef);
UIImage* smallImage = [UIImage imageWithCGImage:subImageRef];
UIGraphicsEndImageContext();
return smallImage;
}
结果发现一个问题,就是截出来的图片相对原图片模糊了许多。于是我写了一个demo把两个方法分开测试了一下,发现是把view转换成图片的时候把屏幕密度改成[UIScreen mainScreen].scale就好了。下面是改过之后的代码:
-(UIImage*)convertViewToImage:(UIView*)v{
CGSize s = v.bounds.size;
// 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了
UIGraphicsBeginImageContextWithOptions(s, YES, [UIScreen mainScreen].scale);
[v.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}