स्पष्ट होने के लिए कैटेक्लेयर में टेक्स्ट कैसे प्राप्त करें


92

मैंने CALayerएक जोड़ा के साथ बनाया है CATextLayerऔर पाठ धुंधली बाहर आता है। डॉक्स में, वे "सब-पिक्सेल एंटीअलियासिंग" के बारे में बात करते हैं, लेकिन इसका मतलब मेरे लिए बहुत मायने नहीं रखता है। किसी के पास एक कोड स्निपेट है जो CATextLayerस्पष्ट पाठ के साथ एक बनाता है?

यहाँ Apple के प्रलेखन से पाठ है:

नोट: CATextLayer पाठ रेंडर करते समय उप-पिक्सेल एंटीलियासिंग को निष्क्रिय कर देता है। पाठ को केवल उप-पिक्सेल एंटीरियलिअसिंग का उपयोग करके खींचा जा सकता है जब इसे मौजूदा अपारदर्शी पृष्ठभूमि में एक ही समय में कंपोज किया जाता है। कोई भी तरीका नहीं है, चाहे वह किसी छवि या परत में हो, अलग से पृष्ठभूमि पिक्सेल रखने के लिए पाठ पिक्सेल बुनाई करने से पहले, उप-एंटीएलियास पाठ को खींचने का कोई तरीका नहीं है। लेयर की अपारदर्शिता गुण को YES में सेट करने से रेंडरिंग मोड में बदलाव नहीं होता है।

दूसरा वाक्य compositesयह existing opaque background at the same time that it's rasterized. बताता है कि यदि किसी को यह बहुत अच्छा लगता है तो उसे अच्छा दिखने वाला पाठ मिल सकता है , लेकिन मैं इसे कैसे संयोजित कर सकता हूं और आप इसे एक अपारदर्शी पृष्ठभूमि कैसे दे सकते हैं और आप इसे कैसे व्यवस्थित कर सकते हैं?

कोड कियोस्क मेनू के अपने उदाहरण में वे जिस कोड का उपयोग करते हैं वह इस प्रकार है: (यह ओएस एक्स है, आईओएस नहीं है, लेकिन मुझे लगता है कि यह काम करता है!)

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);

EDIT 2: नीचे दिए गए मेरे जवाब को देखें कि यह कैसे हल हुआ। SBG।


यह आपके प्रश्न का उत्तर नहीं देगा, लेकिन मेरे जैसे किसी व्यक्ति के लिए प्रासंगिक हो सकता है, जो केवल आरोपित पाठ को आकर्षित करना चाहता है, एक तरीके से सबसे अधिक
यूबिलब

जवाबों:


229

संक्षिप्त उत्तर - आपको स्केलिंग सामग्री सेट करने की आवश्यकता है:

textLayer.contentsScale = [[UIScreen mainScreen] scale];

कुछ समय पहले मुझे पता चला कि जब आपके पास कस्टम ड्राइंग कोड होता है, तो आपको रेटिना डिस्प्ले की जांच करनी होती है और उसी के अनुसार अपने ग्राफिक्स को स्केल करना होता है। UIKitफ़ॉन्ट स्केलिंग सहित, इसका अधिकांश ध्यान रखता है।

इसके साथ ऐसा नहीं है CATextLayer.

मेरा धुंधलापन एक .zPositionशून्य होने से आया था, अर्थात, मेरे पास मेरी पैरेंट लेयर पर एक परिवर्तन था। इसे शून्य पर सेट करने से, धुंधलापन चला गया, और इसे गंभीर पिक्सेलकरण द्वारा बदल दिया गया।

खोज उच्च और निम्न बाद, मैंने पाया आप सेट कर सकते हैं कि .contentsScaleएक के लिए CATextLayerहै और आप इसे करने के लिए सेट कर सकते हैं [[UIScreen mainScreen] scale]स्क्रीन रिज़ॉल्यूशन मैच के लिए। (मुझे लगता है कि यह गैर-रेटिना के लिए काम करता है, लेकिन मैंने जाँच नहीं की है - बहुत थक गया)

इसके बाद मेरे CATextLayerपाठ के लिए यह टेढ़ा हो गया। नोट - यह मूल परत के लिए आवश्यक नहीं है।

और धुंधलापन? जब आप 3D में घूम रहे होते हैं तो यह वापस आ जाता है, लेकिन आप इसे नोटिस नहीं करते क्योंकि टेक्स्ट स्पष्ट होना शुरू होता है और जब यह गति में होता है, तो आप नहीं बता सकते।

समस्या सुलझ गयी!


37
यह संक्षिप्त उत्तर है: textLayer.contentScale = [[UIScreen mainScreen] scale]; BTW, मुझे लंबे उत्तर भी पसंद हैं :)
nacho4d

यह प्रोग्रामर द्वारा बनाए गए किसी भी क्लेयर पर लागू होता है। उदाहरण के लिए, यदि आप देखते हैं कि आपके कैलेयर में खींची गई छवियां रेटिना डिस्प्ले पर क्रिस्प नहीं हैं, तो संभावना है कि यह मुद्दा और समाधान है।
जेफ अर्गास्ट

17
सुधार _textLayer.contentsScale = [[UIScreen mainScreen] scale]; आप एक "s" याद कर रहे हैं;)
Ralphleon

1
यह मेरे लिए काम नहीं करता है। मैं AVVideoCompositionCoreAnimationTool द्वारा एक वीडियो (AVFoundation / AVMutableComposition) के लिए एक CATextLayer जोड़ता हूं। पाठ में अभी भी एलियासिंग है।
vietstone

Mac osx में कोई विकल्प नहीं है
संग्राम शिवंकर

35

तीव्र

स्क्रीन के समान स्केल का उपयोग करने के लिए टेक्स्ट लेयर सेट करें।

textLayer.contentsScale = UIScreen.main.scale

इससे पहले:

यहां छवि विवरण दर्ज करें

उपरांत:

यहां छवि विवरण दर्ज करें


macOS स्विफ्ट 4.2 संस्करण: (NSScreen.main ?backingScaleFactor)!
रोज़बो

17

सबसे पहले मैं यह बताना चाहता था कि आपने अपना प्रश्न iOS के साथ टैग किया है, लेकिन बाधा प्रबंधक केवल OSX पर उपलब्ध हैं, इसलिए मुझे यकीन नहीं है कि जब तक आप इसके खिलाफ लिंक करने में सक्षम नहीं होते हैं, तब तक आपको यह कैसे काम करना है? किसी तरह सिम्युलेटर में। डिवाइस पर, यह कार्यक्षमता उपलब्ध नहीं है।

अगला, मैं सिर्फ यह बताता हूं कि मैं अक्सर कैटेक्लेयर्स बनाता हूं और कभी भी धुंधला होने की समस्या नहीं होती है, इसलिए आप जानते हैं कि यह किया जा सकता है। संक्षेप में यह धुंधलापन इसलिए होता है क्योंकि आप अपनी परत को पूरे पिक्सेल पर नहीं रख रहे हैं। याद रखें कि जब आप एक परत की स्थिति निर्धारित करते हैं, तो आप x और y के लिए एक फ्लोट मान का उपयोग करते हैं। यदि दशमलव के बाद उन मानों की संख्या है, तो परत पूरे पिक्सेल पर तैनात नहीं होगी और इसलिए यह धुंधला प्रभाव देगी - वास्तविक मूल्यों के आधार पर डिग्री। इसका परीक्षण करने के लिए, बस एक कैटेक्लेयर बनाएं और इसे स्पष्ट रूप से लेयर ट्री में जोड़ें ताकि यह सुनिश्चित हो सके कि आपकी स्थिति पैरामीटर पूरे पिक्सेल पर है। उदाहरण के लिए:

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 मानों को निकटतम संपूर्ण पिक्सेल में ले जा सकते हैं और यह आपकी धुंधली समस्या को हल कर सकता है।


15

सेटिंग करने से पहले, आपको चाहिए:

  1. आप जिस लेयर पर रैस्टराइज होने जा रहे हैं, उसके रैस्टराइजेशन सेट करें
  2. किसी भी CATextLayers और संभवतः अन्य प्रकार की परतों की contentScale संपत्ति सेट करें (इसे करने के लिए कभी भी दर्द नहीं होता)

यदि आप # 1 नहीं करते हैं, तो उप परतों के रेटिना संस्करण धुंधले दिखेंगे, यहां तक ​​कि सामान्य क्लेयर्स के लिए भी।

- (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];
}

4

आपको 2 काम करने चाहिए, पहला ऊपर बताया गया है:

CATextLayer बढ़ाएं और रेटिना प्रदर्शन को ठीक से समर्थन करने के लिए अपारदर्शी और contentScale गुणों को सेट करें, फिर पाठ के लिए सक्षम एंटी एलियासिंग के साथ प्रस्तुत करें।

+ (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];
}

3

यदि आप OSX में एक CATextLayer के लिए इसी तरह के मुद्दे के लिए खोज कर रहे हैं, तो बहुत दीवार के सिर को पीटने के बाद, मुझे यह करने से तेज स्पष्ट पाठ मिला:

text_layer.contentsScale = self.window!.backingScaleFactor

(मैं भी दृश्य परत सामग्री सेट सेट करता हूं। समान होने के लिए)।


0

यह तेज़ और आसान है: आपको बस सामग्री सेट करने की आवश्यकता है

    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];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.