【问题标题】:CATextLayer subpixel antialiasingCATextLayer 亚像素抗锯齿
【发布时间】:2014-03-22 22:50:29
【问题描述】:

我的应用在NSImageView 上绘制支持图层的标签。
图像视图显示图像,并在该图像上显示色调。

这可确保标签和背景图像之间的对比度有效。

如您所见,亚像素抗锯齿已启用且工作正常。

当您将鼠标悬停在这些标签上时,它们会为 frame 属性(实际上是包含它们的视图)设置动画。
制作动画时,子像素抗锯齿被禁用,完成后再次启用。

这看起来非常奇怪。

图层永远不会重绘,子像素抗锯齿也不必改变。
所以我看不出在动画时不应该显示它的充分理由。

我已经尝试了所有我能想到的。

  • 使NSTextField 不透明
  • 使CATextLayer 不透明
  • 为NSTextField 提供背景色
  • 给CATextLayer 一个背景色

总是一样的结果。

为标签禁用亚像素抗锯齿不是一种选择,因为它在非视网膜设备上的可读性不好。


编辑

我忘记了在制作动画时图层被替换为presentationLayer。
该层可能不支持亚像素抗锯齿,这就是它被禁用的原因。

现在的问题是我是否可以将这个presentationLayer 替换为CATextLayer。

我还注意到,将shouldRasterize 设置为YES 也为动画启用了亚像素抗锯齿,但仅针对背景颜色。所以没有背景色不会带来亚像素抗锯齿。

【问题讨论】:

  • 这可能什么都不做,但是您是否尝试过在标准 NSView 而不是 NSImageView 上进行文本绘制。几个月前我需要对图像进行注释,最后使用了普通的 NSView,因为我在使用图像视图时遇到了一些奇怪的问题。
  • @boyfarrell 不,刚刚试过。没有效果。
  • 也许您可以从文本图层中获取像素并对其进行动画处理(以 1 个像素为增量?)子像素 AA 实际上取决于图层后面的内容,因此即使您将其设置为工作它可能看起来不正确。
  • @nielsbot 这是一个选项,是的。我得试一试,看看效果如何。
  • 你在做什么?!? :) 我曾经为 Pioneer 工作过,你的图片包含我姓氏的前三个字母和他们的名字。非常可疑。 :)

标签: objective-c macos cocoa core-animation


【解决方案1】:

有什么方法可以发布一段示例代码吗?我快速模拟了一个 NSWindow,添加了一个 NSImageView,添加了一个无背景的 NSTextField,并将 setWantsLayer: 设置为 YES。在我的 applicationDidFinishLaunching 中:我在 NSTextField 的 Animator 框架上设置了一个新的矩形,但我没有看到任何像素化。

【讨论】:

  • 我在问题中写道,在制作动画时会发生这种情况;)
  • 顺便说一句,您需要密切关注。在深色文字上几乎看不到
  • 我知道它在制作动画时会发生,这就是为什么我使用动画代理来调整 NSTextFields 的框架,从而移动了框架的图层。当我使用辅助功能缩放工具提供的缩放放大文本时,我确实看到了这种情况。当我切换应用程序时,我也看到了这种情况。但是如果你不放大文本或切换应用程序,它看起来很正常。即使调整窗框也不会引入像素化。当我将应用程序带到前台时,我发现在 NSTextField 层上调用 setNeedsDisplay 删除了任何像素化。
  • 尝试在深色背景中添加白色文本,然后制作动画。你会看到它更加明显。动画停止后,子像素 AA 再次启用,一切正常。
  • 我很好奇你看到了什么行为。
【解决方案2】:

问题在于文本层的定位。假设您使用左对齐。如果图层框架原点的 x 和 y 坐标是四舍五入的数字,则文本看起来不错。例如:

CGFloat x = 10.6;
CGFloat y = 10.3;

textLayer.frame = CGRectMake(x, y, width, height); // the text will be blur.
textLayer.frame = CGRectMake(round(x), round(y), width, height); // the text will not be blur.

所以,第一个问题可能是您分配给图层框架的坐标没有四舍五入。 棘手的部分是即使您认为您传递了圆角坐标,图层的边缘仍可能未与像素对齐。如果您的图层的锚点为(0.5, 0.5)(这是默认值),则可能会发生这种情况。如果你设置:

textLayer.position = CGPointMake(10.0, 10.0);

您可能认为它应该使文本清晰。但是,这里的位置点在图层的中心,根据图层的宽度和高度,左上边缘的坐标可能是小数。

如果您想进行快速测试,请执行此操作。

  1. 使用textLayer.frame = frame而不是使用位置和锚点,它会将坐标直接分配给框架。
  2. 确保您在框架中使用的数字是四舍五入的。
  3. 不要乱用渲染机制,去掉改变shouldRasterize、antialiasing等的代码。

如果这使文本清晰,您可以开始使用锚点和位置并查看结果如何变化。

【讨论】:

  • 不幸的是,这也不是问题所在。在制作 alpha 动画时,甚至禁用了子像素 AA,这不允许这种可能性。
猜你喜欢
  • 1970-01-01
  • 2015-11-23
  • 2011-05-31
  • 1970-01-01
  • 2012-12-03
  • 2011-05-22
  • 2014-02-18
  • 2011-07-30
  • 1970-01-01
相关资源
最近更新 更多