从UIView获取的UIImage分辨率高于屏幕分辨率吗?

20

我有一个UIView,通过典型的UIGraphicsBeginImageContextWithOptions方法将其渲染为UIImage,使用2.0倍比例尺寸,这样输出的图像将始终是“视网膜显示”版本,无论用户实际屏幕分辨率如何。

我要渲染的UIView包含图像和文本(UIImages和UILabels)。该图像在渲染的UIImage中以其完整分辨率出现,并且效果很好。但是UILabel似乎已经被光栅化为1.0倍并放大到2.0倍,导致文本模糊不清。

我是否做错了什么,或者有没有一种方法可以以更高的比例水平呈现文本?还是有没有其他方法可以产生更好的结果,而不是使用UIGraphicsBeginImageContextWithOptions的缩放参数?谢谢!

3个回答

10
解决方案是在绘制标签之前将其内容的contentsScale更改为2,然后立即设置回来。我刚刚编写了一个项目来验证它,在普通视网膜手机(模拟器)上制作2倍图像,它工作得非常好。[如果您有可以放置它的公共场所,请告诉我。] 编辑:扩展代码遍历子视图和任何容器UIView以设置/取消比例。
- (IBAction)snapShot:(id)sender
{
    [self changeScaleforView:snapView scale:2];

    UIGraphicsBeginImageContextWithOptions(snapView.bounds.size, snapView.opaque, 2);
    [snapView.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    imageDisplay.image = img; // contentsScale
    imageDisplay.contentMode = UIViewContentModeScaleAspectFit;

    [self changeScaleforView:snapView scale:1];
}

- (void)changeScaleforView:(UIView *)aView scale:(CGFloat)scale
{
    [aView.subviews enumerateObjectsUsingBlock:^void(UIView *v, NSUInteger idx, BOOL *stop)
        {
            if([v isKindOfClass:[UILabel class]]) {
                v.layer.contentsScale = scale;
            } else
            if([v isKindOfClass:[UIImageView class]]) {
                // labels and images
                // v.layer.contentsScale = scale; won't work

                // if the image is not "@2x", you could subclass UIImageView and set the name of the @2x
                // on it as a property, then here you would set this imageNamed as the image, then undo it later
            } else
            if([v isMemberOfClass:[UIView class]]) {
                // container view
                [self changeScaleforView:v scale:scale];
            }       
        } ];
}

这个方法是可行的,但如果你想捕获一个UITableView,逐层单独更改每个图层会很麻烦。难道没有一种递归地为所有子视图更改它的方法吗? - charliehorse55
1
我不知道有任何单一的命令,但请注意扩展代码将递归并完成大部分工作。如果您没有将imageViews设置为2倍图像(对于非Retina显示器可以正常工作,但在渲染时会给系统带来更多的工作),则需要进行特殊处理。 - David H

2
尝试使用双倍大小进行图像渲染,然后创建缩放图像:
UIGraphicsBeginImageContextWithOptions(size, NO, 1.0);
// Do stuff
UImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

newImage=[UIImage imageWithCGImage:[newImage CGImage] scale:2.0 orientation:UIImageOrientationUp];

在这里: 大小 = 实际大小 * 缩放比例;


我不确定我理解你的意思。我没有使用 CGImage,我有一个 UIView,然后将其渲染成 UIImage… - DanM
已编辑。它应该做你想要的事情。 - unexpectedvalue
1
这难道不会把所有东西都放大吗?所以现在文本和图像都会变得模糊吗? - DanM
1
尝试一下。您可以将其渲染到大纹理上,分辨率加倍,然后创建缩放版本。 - unexpectedvalue
在此模式下,文本和其他几个用户界面元素仍然有些模糊。 - charliehorse55
这个很好用。抱怨文本模糊的人似乎错过了最后一步,即将双倍缩放的图像缩小至1.0。 - Bruno Philipe

0

我在文本视图转换为PDF时遇到了类似的问题。我发现视图中的CALayer对象有一些已记录的属性。也许设置相关(子)层的光栅化比例可以帮助解决问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接