我有一个使用 CGAffineTransform 旋转的 UIImageView(全帧和矩形)。UIImageView 的 UIImage 填满了整个框架。当图像被旋转和绘制时,边缘出现明显的锯齿状。我能做些什么让它看起来更好吗?它显然没有与背景抗锯齿。
8 回答
在 iOS 上默认情况下 CoreAnimation 层的边缘没有抗锯齿。但是,您可以在 Info.plist 中设置一个启用边缘抗锯齿的键:UIViewEdgeAntialiasing。
如果您不希望启用此选项的性能开销,解决方法是在图像边缘周围添加 1px 透明边框。这意味着图像的“边缘”不再在边缘,所以不需要特殊处理!
新 API – iOS 6/7
正如@Chris 所指出的,也适用于 iOS 6,但直到 iOS 7 才公开。
从 iOS 7 开始,CALayer 有了一个新属性allowsEdgeAntialiasing
,在这种情况下完全可以满足您的需求,而不会产生为应用程序中的所有视图启用它的开销!这是 CALayer 的一个属性,因此要为您使用的 UIView 启用它 myView.layer.allowsEdgeAntialiasing = YES
。
只需为您的图像添加 1px 透明边框
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[image drawInRect:CGRectMake(1,1,image.size.width-2,image.size.height-2)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
请记住设置适当的抗锯齿选项:
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);
只需在 plist 中添加“带有边缘抗锯齿的渲染”和 YES 即可。
我完全推荐以下库。
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
它包含许多有用的 UIImage 扩展来解决这个问题,还包括用于生成缩略图等的代码。
享受!
我发现拥有平滑边缘和清晰图像的最佳方法是这样做:
CGRect imageRect = CGRectMake(0, 0, self.photo.image.size.width, self.photo.image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[self.photo.image drawInRect:CGRectMake(1, 1, self.photo.image.size.width - 2, self.photo.image.size.height - 2)];
self.photo.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
像某些人描述的那样添加 Info.plist 键会对性能产生很大影响,如果您使用它,那么您基本上会将其应用于所有内容,而不仅仅是您需要的地方。
另外,不要只使用,UIGraphicsBeginImageContext(imageRect.size);
否则图层会模糊。你必须UIGraphicsBeginImageContextWithOptions
像我展示的那样使用。
我从这里找到了这个解决方案,它很完美:
+ (UIImage *)renderImageFromView:(UIView *)view withRect:(CGRect)frame transparentInsets:(UIEdgeInsets)insets {
CGSize imageSizeWithBorder = CGSizeMake(frame.size.width + insets.left + insets.right, frame.size.height + insets.top + insets.bottom);
// Create a new context of the desired size to render the image
UIGraphicsBeginImageContextWithOptions(imageSizeWithBorder, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Clip the context to the portion of the view we will draw
CGContextClipToRect(context, (CGRect){{insets.left, insets.top}, frame.size});
// Translate it, to the desired position
CGContextTranslateCTM(context, -frame.origin.x + insets.left, -frame.origin.y + insets.top);
// Render the view as image
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
// Fetch the image
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
// Cleanup
UIGraphicsEndImageContext();
return renderedImage;
}
用法:
UIImage *image = [UIImage renderImageFromView:view withRect:view.bounds transparentInsets:UIEdgeInsetsZero];