如何让文本在CATextLayer中清晰
我用一个添加的CATextLayer
做了一个CALayer
,文本出来模糊。 在文档中,他们谈论的是“亚像素抗锯齿”,但这对我来说没有多大意义。 任何人都有一个代码片段,使一个CATextLayer
与一些文本是清晰的?
以下是苹果文档中的文字:
注意:CATextLayer在渲染文本时禁用子像素抗锯齿。 只有在光栅化的同时将文本合成到现有的不透明背景中时,才能使用子像素抗锯齿绘制文本。 无论是将像素反锯齿的文本本身绘制成图像还是图层,都无法将背景像素编织成文本像素。 将图层的不透明属性设置为YES不会更改呈现模式。
第二句话意味着如果existing opaque background at the same time that it's rasterized.
composites
到existing opaque background at the same time that it's rasterized.
则可以获得好看的文本existing opaque background at the same time that it's rasterized.
那太好了,但是我怎么把它复合起来,你怎么给它一个不透明的背景,怎么把它光栅化呢?
他们在Kiosk菜单示例中使用的代码是这样的:(它是OS X,不是iOS,但是我认为它可行!)
NSInteger i; for (i=0;i<[names count];i++) { CATextLayer *menuItemLayer=[CATextLayer layer]; menuItemLayer.string=[self.names objectAtIndex:i]; menuItemLayer.font=@"Lucida-Grande"; menuItemLayer.fontSize=fontSize; menuItemLayer.foregroundColor=whiteColor; [menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY relativeTo:@"superlayer" attribute:kCAConstraintMaxY offset:-(i*height+spacing+initialOffset)]]; [menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX relativeTo:@"superlayer" attribute:kCAConstraintMidX]]; [self.menuLayer addSublayer:menuItemLayer]; } // end of for loop
谢谢!
编辑:添加我实际使用的代码导致模糊的文本。 这是从一个相关的问题,我发布了关于添加一个UILabel
而不是一个CATextLayer
而是得到一个黑盒子。 http://stackoverflow.com/questions/3818676/adding-a-uilabels-layer-to-a-calayer-and-it-just-shows-black-box
CATextLayer* upperOperator = [[CATextLayer alloc] init]; CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); CGFloat components1[4] = {1.0, 1.0, 1.0, 1.0}; CGColorRef almostWhite = CGColorCreate(space,components1); CGFloat components2[4] = {0.0, 0.0, 0.0, 1.0}; CGColorRef almostBlack = CGColorCreate(space,components2); CGColorSpaceRelease(space); upperOperator.string = [NSString stringWithFormat:@"13"]; upperOperator.bounds = CGRectMake(0, 0, 100, 50); upperOperator.foregroundColor = almostBlack; upperOperator.backgroundColor = almostWhite; upperOperator.position = CGPointMake(50.0, 25.0); upperOperator.font = @"Helvetica-Bold"; upperOperator.fontSize = 48.0f; upperOperator.borderColor = [UIColor redColor].CGColor; upperOperator.borderWidth = 1; upperOperator.alignmentMode = kCAAlignmentCenter; [card addSublayer:upperOperator]; [upperOperator release]; CGColorRelease(almostWhite); CGColorRelease(almostBlack);
编辑2:看到我的答案如何解决这个问题。 SBG。
简短的回答 – 你需要设置内容缩放:
textLayer.contentsScale = [[UIScreen mainScreen] scale];
前一阵子我了解到,当你有自定义的绘图代码,你必须检查视网膜显示,并相应地缩放您的graphics。 UIKit
负责处理大部分内容,包括字体缩放。
与CATextLayer.
我的模糊来自一个.zPosition
不是零,也就是说,我有一个变换应用到我的父层。 通过将其设置为零,模糊性消失,并被严重的像素化所取代。
高低search后,我发现你可以设置.contentsScale
为一个CATextLayer
,你可以将其设置为[[UIScreen mainScreen] scale]
以匹配屏幕分辨率。 (我认为这适用于非视网膜,但我没有检查 – 太累了)
包括这个为我的CATextLayer
,文本变得清脆。 注意 – 父层不需要。
而模糊? 当你在3D中旋转时,它会回来,但是你没有注意到,因为文本开始清晰,而在运动中,你不能说。
问题解决了!
首先,我想指出你已经用iOS标记了你的问题,但是约束pipe理器只能在OSX上使用,所以我不确定你是如何得到这个工作的,除非你能够链接到它在模拟器不知何故。 在设备上,此function不可用。
接下来,我将指出我经常创buildCATextLayer,并且从来没有模糊的问题,所以我知道这是可以做到的。 简而言之,这种模糊发生是因为你没有在整个像素上定位你的图层。 请记住,当您设置图层的位置时,可以使用x和y的浮点值。 如果这些值在小数点后面有数字,那么图层将不会被放置在整个像素上,因此会产生这种模糊效果 – 其程度取决于实际值。 为了testing这个,只需创build一个CATextLayer并明确地将其添加到图层树中,以确保您的位置参数位于整个像素上。 例如:
CATextLayer *textLayer = [CATextLayer layer]; [textLayer setBounds:CGRectMake(0.0f, 0.0f, 200.0f, 30.0f)]; [textLayer setPosition:CGPointMake(200.0f, 100.0f)]; [textLayer setString:@"Hello World!"]; [[self menuLayer] addSublayer:textLayer];
如果你的文字仍然模糊,那么还有其他的错误。 文字图层上的模糊文字是不正确编写的代码的人工产物,而不是图层的预期function。 将图层添加到父图层时,只需将x和y值强制为最接近的整个像素即可解决您的模糊问题。
最好的祝福。
在设置shouldRasterize之前,您应该:
- 设置您要栅格化的基础图层的rasterizationScale
- 设置任何CATextLayers和可能的其他types的图层的contentsScale属性(它永远不会伤害它)
如果你没有做#1,那么视网膜版本的子图层看起来就会模糊,即使对于正常的CALayers也是如此。
- (void)viewDidLoad { [super viewDidLoad]; CALayer *mainLayer = [[self view] layer]; [mainLayer setRasterizationScale:[[UIScreen mainScreen] scale]]; CATextLayer *messageLayer = [CATextLayer layer]; [messageLayer setForegroundColor:[[UIColor blackColor] CGColor]]; [messageLayer setContentsScale:[[UIScreen mainScreen] scale]]; [messageLayer setFrame:CGRectMake(50, 170, 250, 50)]; [messageLayer setString:(id)@"asdfasd"]; [mainLayer addSublayer:messageLayer]; [mainLayer setShouldRasterize:YES]; }
设置文本图层使用与屏幕相同的比例。
textLayer.contentsScale = UIScreen.main.scale
之前:
后:
你应该做两件事,第一件是上面提到的:
扩展CATextLayer并设置opaque和contentsScale属性以正确支持视网膜显示,然后为文本启用反锯齿function。
+ (TextActionLayer*) layer { TextActionLayer *layer = [[TextActionLayer alloc] init]; layer.opaque = TRUE; CGFloat scale = [[UIScreen mainScreen] scale]; layer.contentsScale = scale; return [layer autorelease]; } // Render after enabling with anti aliasing for text - (void)drawInContext:(CGContextRef)ctx { CGRect bounds = self.bounds; CGContextSetFillColorWithColor(ctx, self.backgroundColor); CGContextFillRect(ctx, bounds); CGContextSetShouldSmoothFonts(ctx, TRUE); [super drawInContext:ctx]; }
如果你在这里searchOSX的CATextLayer类似的问题,经过很长时间的敲门之后,我通过这样做了清晰的文字:
text_layer.contentsScale = self.window!.backingScaleFactor
(我也设置视图背景层contentsScale是一样的)。
这是更快,更容易:你只需要设置contentsScale
CATextLayer *label = [[CATextLayer alloc] init]; [label setFontSize:15]; [label setContentsScale:[[UIScreen mainScreen] scale]]; [label setFrame:CGRectMake(0, 0, 50, 50)]; [label setString:@"test"]; [label setAlignmentMode:kCAAlignmentCenter]; [label setBackgroundColor:[[UIColor clearColor] CGColor]]; [label setForegroundColor:[[UIColor blackColor] CGColor]]; [self addSublayer:label];