具有缩放变换的模糊 CATextLayer
Blurry CATextLayer with scale transform
我已经无计可施了。我已经尝试了我认为可以摆脱 CATextLayer
模糊的所有方法,但都无济于事。不可否认,有些事情有帮助,但当放大 2 倍时文本仍然太模糊,远不及非 CATextLayer
文本的清晰度。
这是我的情况。我有一个层托管视图,它可以包含许多子层,包括 CATextLayers
(在自定义 CALayer
容器内)。现在,用户可以缩放主要内容层(包含所有子层内容),这是通过对内容层应用缩放变换来完成的。
这是我目前正在做的事情。大多数都会有所作为,尽管差别不大。如果我一直放大(2 倍比例因子),我会得到非常模糊的文字。
确保积分坐标 - 有效并产生明显的差异,但在 2x 比例下仍然太模糊
关闭 CATextLayer
容器层上的阴影 - 虽然不是 2 倍比例但有所不同
确保文本图层的背景颜色完全不透明 - 虽然不是 2 倍比例,但似乎有所不同
将所有层的 contentsScale
属性 设置为 window 支持比例因子 - 虽然不是 2x 比例,但似乎有所不同
重写此自定义 CATextLayer
子类的 -drawInContext:
以平滑、抗锯齿和子像素量化一切 - 字体渲染更真实,但仍然2 倍模糊
代码片段:
- (void) drawInContext:(CGContextRef)context
{
// Allow font smoothing.
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetAllowsFontSmoothing(context, YES);
CGContextSetAllowsFontSubpixelPositioning(context, YES);
CGContextSetAllowsFontSubpixelQuantization(context, YES);
// Set drawing attributes.
CGContextSetStrokeColorWithColor(context, self.foregroundColor);
CGContextSetFillColorWithColor(context, self.backgroundColor);
CGContextFillRect(context, self.bounds);
// Font smoothing.
CGContextSetShouldAntialias(context, YES);
CGContextSetShouldSmoothFonts(context, YES);
CGContextSetShouldSubpixelPositionFonts(context, YES);
CGContextSetShouldSubpixelQuantizeFonts(context, YES);
[super drawInContext:context];
}
我错过了什么?
对于尽可能清晰的文本,除了原始问题中提到的所有内容之外,影响最大的解决方案是将文本层的 contentsScale
值加倍到 window 背景的两倍scale factor - 如果你想支持 2 倍缩放的清晰文本。
如果您想在较高的缩放值下支持清晰的文本,请使用您的应用程序的最大缩放系数作为调整后的 contentsScale
。例如,您可以通过覆盖自定义 CATextLayer
子类的 -setContentsScale:
来执行此操作:
- (void) setContentsScale:(CGFloat)contentsScale
{
[super setContentsScale:contentsScale * kMaxZoomFactor];
}
请注意,请确保通过覆盖层托管视图的 -viewDidChangeBackingProperties
将视图支持属性的更改(例如,更改为具有更高分辨率的屏幕)传播到层托管层次结构:
- (void) viewDidChangeBackingProperties
{
// Propagate self.window.backingScaleFactor change to layer hierarchy.
}
我已经无计可施了。我已经尝试了我认为可以摆脱 CATextLayer
模糊的所有方法,但都无济于事。不可否认,有些事情有帮助,但当放大 2 倍时文本仍然太模糊,远不及非 CATextLayer
文本的清晰度。
这是我的情况。我有一个层托管视图,它可以包含许多子层,包括 CATextLayers
(在自定义 CALayer
容器内)。现在,用户可以缩放主要内容层(包含所有子层内容),这是通过对内容层应用缩放变换来完成的。
这是我目前正在做的事情。大多数都会有所作为,尽管差别不大。如果我一直放大(2 倍比例因子),我会得到非常模糊的文字。
确保积分坐标 - 有效并产生明显的差异,但在 2x 比例下仍然太模糊
关闭
CATextLayer
容器层上的阴影 - 虽然不是 2 倍比例但有所不同确保文本图层的背景颜色完全不透明 - 虽然不是 2 倍比例,但似乎有所不同
将所有层的
contentsScale
属性 设置为 window 支持比例因子 - 虽然不是 2x 比例,但似乎有所不同重写此自定义
CATextLayer
子类的-drawInContext:
以平滑、抗锯齿和子像素量化一切 - 字体渲染更真实,但仍然2 倍模糊
代码片段:
- (void) drawInContext:(CGContextRef)context
{
// Allow font smoothing.
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetAllowsFontSmoothing(context, YES);
CGContextSetAllowsFontSubpixelPositioning(context, YES);
CGContextSetAllowsFontSubpixelQuantization(context, YES);
// Set drawing attributes.
CGContextSetStrokeColorWithColor(context, self.foregroundColor);
CGContextSetFillColorWithColor(context, self.backgroundColor);
CGContextFillRect(context, self.bounds);
// Font smoothing.
CGContextSetShouldAntialias(context, YES);
CGContextSetShouldSmoothFonts(context, YES);
CGContextSetShouldSubpixelPositionFonts(context, YES);
CGContextSetShouldSubpixelQuantizeFonts(context, YES);
[super drawInContext:context];
}
我错过了什么?
对于尽可能清晰的文本,除了原始问题中提到的所有内容之外,影响最大的解决方案是将文本层的 contentsScale
值加倍到 window 背景的两倍scale factor - 如果你想支持 2 倍缩放的清晰文本。
如果您想在较高的缩放值下支持清晰的文本,请使用您的应用程序的最大缩放系数作为调整后的 contentsScale
。例如,您可以通过覆盖自定义 CATextLayer
子类的 -setContentsScale:
来执行此操作:
- (void) setContentsScale:(CGFloat)contentsScale
{
[super setContentsScale:contentsScale * kMaxZoomFactor];
}
请注意,请确保通过覆盖层托管视图的 -viewDidChangeBackingProperties
将视图支持属性的更改(例如,更改为具有更高分辨率的屏幕)传播到层托管层次结构:
- (void) viewDidChangeBackingProperties
{
// Propagate self.window.backingScaleFactor change to layer hierarchy.
}