Как получить текст в CATextLayer, чтобы быть понятным
Я сделал CALayer
с добавленным CATextLayer
, и текст получился размытым. В документах они говорят о "подпиксельном сглаживании", но это не значит для меня. У кого-нибудь есть фрагмент кода, который делает CATextLayer
с четким текстом?
Здесь текст из документации Apple:
Примечание. CATextLayer отключает сглаживание подпикселя при рендеринге текста. Текст можно рисовать только с помощью сглаживания подпикселя, когда он скомпонованы в существующий непрозрачный фон в то же время, что он растеризован. Невозможно нарисовать текст подпиксельной сглаживания себя, будь то изображение или слой, отдельно перед имеющие фоновые пиксели для ткачества текстовых пикселей. настройка свойство непрозрачности слоя к YES не изменяет рендеринг Режим.
Второе предложение подразумевает, что можно получить красивый текст, если один composites
он в existing opaque background at the same time that it rasterized.
Это здорово, но как я его составлю и как вы даете ему непрозрачный фон и как вы его растеризуете?
Код, который они используют в своем примере меню киоска, таков: (Это OS X, а не iOS, но я предполагаю, что это работает!)
NSInteger i;
for (i=0;i<[names count];i++) {
CATextLayer *menuItemLayer=[CATextLayer layer];
menuItemLayer.string=[self.names objectAtIndex:i];
[email protected]"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
Спасибо!
EDIT: добавление кода, который я фактически использовал, который привел к размытому тексту. Это из связанного вопроса, который я написал о добавлении UILabel
, а не в CATextLayer
, но вместо этого получал черный ящик. http://stackoverflow.com/info/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.
Ответы
Ответ 1
Короткий ответ - вам нужно настроить масштабирование содержимого:
textLayer.contentsScale = [[UIScreen mainScreen] scale];
Некоторое время назад я узнал, что, когда у вас есть пользовательский код рисования, вы должны проверить отображение сетчатки и масштабировать свою графику соответствующим образом. UIKit
выполняет большую часть этого, включая масштабирование шрифта.
Не так с CATextLayer.
Моя размытость возникла из-за того, что .zPosition
не был нулевым, т.е. у меня было преобразование, применяемое к моему родительскому слою. Установив это на ноль, размытость исчезла и была заменена серьезной пикселизацией.
После поиска высокого и низкого уровня я обнаружил, что вы можете установить .contentsScale
для CATextLayer
, и вы можете установить его на [[UIScreen mainScreen] scale]
в соответствии с разрешением экрана. (Я предполагаю, что это работает для не-сетчатки, но я не проверил - слишком устал)
После включения этого для моего CATextLayer
текст стал четким. Примечание - это не обязательно для родительского слоя.
И размытость? Он возвращается, когда вы вращаетесь в 3D, но вы этого не замечаете, потому что текст начинается четким и пока он в движении, вы не можете сказать.
Проблема решена!
Ответ 2
Сначала я хотел указать, что вы отметили свой вопрос с помощью iOS, но менеджеры ограничений доступны только на OSX, поэтому я не уверен, как вы это делаете, если не сможете ссылка на него в симуляторе как-то. На устройстве эта функция недоступна.
Затем я просто укажу, что я часто создаю CATextLayers и никогда не сталкиваюсь с проблемой размытия, о которой вы говорите, поэтому я знаю, что это можно сделать. В двух словах это размывание происходит потому, что вы не позиционируете свой слой на весь пиксель. Помните, что когда вы устанавливаете положение слоя, вы используете значения float для x и y. Если эти значения имеют числа после десятичного знака, слой не будет располагаться на всем пикселе и поэтому даст этот эффект размытия - степень которого зависит от фактических значений. Чтобы проверить это, просто создайте 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];
Если текст по-прежнему размыт, значит, что-то еще не так. Размытый текст на вашем текстовом слое является артефактом неправильно написанного кода, а не предполагаемой способностью слоя. При добавлении слоев к родительскому слою вы можете просто принудить значения x и y к ближайшему целому пикселю, и это должно решить вашу проблему размытия.
Ответ 3
Swift
Установите для текстового слоя тот же масштаб, что и экран.
textLayer.contentsScale = UIScreen.main.scale
Перед
![введите описание изображения здесь]()
После того, как:
![введите описание изображения здесь]()
Ответ 4
Перед настройкой shouldRasterize вы должны:
- установите растеризациюScale базового слоя, который вы собираетесь растрировать
- установить свойство contentsScale любых CATextLayers и, возможно, других типов слоев (это никогда не мешает это делать)
Если вы не делаете # 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];
}
Ответ 5
Вы должны сделать 2 вещи, первое было упомянуто выше:
Расширьте CATextLayer и установите свойства opaque и contentsScale для правильной поддержки отображения сетчатки, а затем визуализируйте с включенным сглаживанием для текста.
+ (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];
}
Ответ 6
Если вы искали здесь аналогичную проблему для CATextLayer в OSX, после того, как сильно ударили по стене, я получил четкий текст, выполнив:
text_layer.contentsScale = self.window!.backingScaleFactor
(Я также устанавливаю, что содержание фонового слоя ViewsScale одинаковое).
Ответ 7
Это быстрее и проще: вам просто нужно установить 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];