【问题标题】:renderInContext: producing an image with blurry textrenderInContext:生成带有模糊文本的图像
【发布时间】:2012-04-15 22:44:41
【问题描述】:

我正在使用几个不同的 UIImageViews 和 UILabels 预渲染合成图像,以加快在大型 tableview 中的滚动。不幸的是,与同一视图上的其他 UILabel 相比,主 UILabel 看起来有点模糊。

UILabel 中的黑色字母“PLoS ONE”看起来比“Medical”或“Medicine”要模糊得多。 “PLoS one”的标志可能同样被模糊了,但不如清晰的文字那么明显。
整个杂志封面是分配给 UIButton 的单个 UIImage。


(来源:karlbecker.com

这是我用来绘制图像的代码。 MagazineView 是一个 125 x 151 像素的矩形。 我尝试了不同的缩放质量,但这并没有改变任何东西。它不应该,因为缩放不应该是不同的。我分配此图像的 UIButton 与 magazineView 的大小完全相同。

    UIGraphicsBeginImageContextWithOptions(magazineView.bounds.size, NO, 0.0);
    [magazineView.layer renderInContext:UIGraphicsGetCurrentContext()];
    [coverImage release];
    coverImage = UIGraphicsGetImageFromCurrentImageContext();
    [coverImage retain];
    UIGraphicsEndImageContext();

任何想法为什么它是模糊的?

当我开始一个图像上下文并立即渲染到它时,渲染是在一个偶数像素上发生的,还是我需要手动设置渲染发生的位置?

【问题讨论】:

  • 125 x 151 像素,还是点?如果是后者,如果您为 Retina 构建并在模拟器中逐个像素地查看它会怎样?您是否发现文本实际上是模糊的,或者像素加倍?
  • 我注意到模拟器不会呈现完美边缘的文本,但在手机本身上效果很好。我不知道这是否是你的情况。
  • @Peter:感谢您的更正 - 它是 125 x 151 点,因为我是从视图的 frame 属性中得到的。 Retina display from Simulator 在 Retina 的模拟器上看起来非常好(请注意,艺术品尚未针对 Retina 升级) Inturbidus:在设备和模拟器上相同,至少对于普通 iPad。 Retina 文字看起来好多了,好多了……无法解释其中的区别。
  • 你有没有想过这个问题?我们在我们的应用程序中看到了同样的问题(使用整数值作为大小/矩形)。我们将 UITextLabel 绘制到图像中以用于缓存目的,但在 Retina 显示器上它都是模糊的,就像图像已按比例放大(我认为它已放大)。如果我们将尺寸加倍,则文本太小。
  • 原来你需要使用 UIGraphicsBeginImageContextWithOptions(size, YES, [UIScreen mainScreen].scale);为了支持视网膜和非视网膜显示器。

标签: ios cocoa-touch uikit


【解决方案1】:

确保您的标签坐标是整数值。如果它们不是整数,它们会显得模糊。

【讨论】:

    【解决方案2】:

    我认为您需要使用 CGRectIntegral 了解更多信息,请参阅: What is the usage of CGRectIntegral? Reference of CGRectIntegral

    【讨论】:

      【解决方案3】:

      我今天遇到了同样的问题,当我从 UILabel 文本生成图像时,我的内容被像素化了。

      我们使用UIGraphicsBeginImageContextWithOptions()来配置绘制环境以渲染成一个接受三个参数的位图:

      size:新位图上下文的大小。这表示 UIGraphicsGetImageFromCurrentImageContext 函数返回的图像的大小。

      opaque:一个布尔标志,指示位图是否不透明。如果 opaque 参数为 YES,则忽略 alpha 通道并将位图视为完全不透明。

      scale:应用于位图的比例因子。如果您指定值 0.0,则比例因子设置为设备主屏幕的比例因子。

      所以我们应该针对设备显示使用适当的比例因子(1x、2x、3x)来解决这个问题。

      Swift 5 版本:

      UIGraphicsBeginImageContextWithOptions(frame.size, true, UIScreen.main.scale)
      if let currentContext = UIGraphicsGetCurrentContext() {
          nameLabel.layer.render(in: currentContext)
          let nameImage = UIGraphicsGetImageFromCurrentImageContext()
          return nameImage
      }
      

      【讨论】:

        猜你喜欢
        • 2012-06-27
        • 2014-05-13
        • 1970-01-01
        • 2020-02-07
        • 2022-12-18
        • 1970-01-01
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多