কীভাবে CATextLayer এ পাঠ্য পাবেন তা পরিষ্কার হয়ে যাবে


92

আমি CALayerএকটি যুক্ত দিয়ে একটি তৈরি করেছি CATextLayerএবং পাঠ্যটি ঝাপসা হয়ে আসে। দস্তাবেজে, তারা "সাব-পিক্সেল অ্যান্টিয়ালাইজিং" সম্পর্কে কথা বলছেন, তবে এটি আমার কাছে খুব বেশি বোঝায় না। যে কারও কাছে একটি কোড স্নিপেট রয়েছে যা CATextLayerকিছুটা টেক্সট দিয়ে স্পষ্ট করে তোলে ?

অ্যাপলের ডকুমেন্টেশন থেকে লেখাটি এখানে:

দ্রষ্টব্য: পাঠ্য রেন্ডার করার সময় 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);

সম্পাদনা 2: এটি কীভাবে সমাধান হয়েছে তার নীচে আমার উত্তর দেখুন। sbg।


এটি আপনার প্রশ্নের উত্তর দিতে হবে না, কিন্তু আমার মত কেউ শুধুমাত্র আরোপিত টেক্সট আঁকা খুঁজছেন হয় জন্য প্রাসঙ্গিক UILabel ব্যবহার সবচেয়ে অনুরূপ হতে পারে একটি পদ্ধতিতে: stackoverflow.com/questions/3786528/...
DenNukem

উত্তর:


229

সংক্ষিপ্ত উত্তর - আপনার বিষয়বস্তু স্কেলিং সেট করতে হবে:

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

কিছুক্ষণ আগে আমি শিখেছি যখন আপনার কাস্টম অঙ্কন কোড রয়েছে তখন আপনাকে রেটিনা ডিসপ্লেটি পরীক্ষা করতে হবে এবং সেই অনুযায়ী আপনার গ্রাফিকগুলি স্কেল করতে হবে। UIKitফন্ট স্কেলিং সহ এর বেশিরভাগের যত্ন নেয়।

তাই না CATextLayer.

আমার অস্পষ্টতা .zPositionশূন্য নয় এমনটি হ'ল , এটি আমার প্যারেন্ট লেয়ারে রূপান্তরিত হয়েছিল। এটিকে শূন্যে সেট করে দিয়ে, অস্পষ্টতা চলে গেল এবং গুরুতর পিক্সিলেশন দ্বারা প্রতিস্থাপিত হয়েছিল।

উচ্চ এবং নিম্ন অনুসন্ধানের পরে, আমি দেখতে পেলাম যে আপনি .contentsScaleএকটি CATextLayerসেট করতে পারেন এবং আপনি [[UIScreen mainScreen] scale]এটি পর্দার রেজোলিউশনের সাথে মেলে সেট করতে পারেন । (আমি ধরেছি এটি রেটিনাবিহীন জন্য কাজ করে তবে আমি পরীক্ষা করে দেখিনি - খুব ক্লান্ত)

আমার CATextLayerলেখার জন্য এটি অন্তর্ভুক্ত করার পরে খাস্তা হয়ে গেল। দ্রষ্টব্য - এটি পিতামাতার স্তরের জন্য প্রয়োজনীয় নয়।

আর অস্পষ্টতা? আপনি যখন 3D তে ঘুরছেন তখন এটি ফিরে আসবে, তবে আপনি এটি লক্ষ্য করবেন না কারণ পাঠ্যটি স্পষ্টভাবে শুরু হয়ে গেছে এবং এটি চলমান অবস্থায় আপনি বলতে পারবেন না।

সমস্যা সমাধান!


37
এটি সংক্ষিপ্ত উত্তর: textLayer.contentScale = [[UIScreen mainScreen] scale]; বিটিডাব্লু, আমি দীর্ঘ উত্তরগুলিও পছন্দ করি :)
nacho4d

এটি প্রোগ্রামালিমে তৈরি হওয়া যে কোনও ক্যালায়ারের ক্ষেত্রে প্রযোজ্য। উদাহরণস্বরূপ, আপনি যদি খেয়াল করেন যে আপনার ক্যালিয়ারে আঁকা চিত্রগুলি রেটিনা ডিসপ্লেতে খাস্তা নয়, সম্ভবত এটিই সমস্যা এবং সমাধান।
জেফ আরগাস্ট

17
সংশোধন _textLayer.contentsScale = [[UIScreen mainScreen] scale]; আপনি একটি "s" মিস করছেন;)
র‌্যালফ্লিয়ন 16'12

4
এটি আমার পক্ষে কাজ করে না। আমি AVVideoCompositionCoreAnimationTool দ্বারা একটি ভিডিওতে (AVFoundation / AVMutableComposition) একটি ক্যাটেক্সটায়ার যুক্ত করি। পাঠ্যটিতে এখনও অ্যালিজিং রয়েছে।
ভাইসটোন

ম্যাক
ওএসএক্সে

35

সুইফট

স্ক্রিনের মতো একই স্কেলটি ব্যবহার করতে পাঠ্য স্তরটি সেট করুন।

textLayer.contentsScale = UIScreen.main.scale

আগে:

এখানে চিত্র বর্ণনা লিখুন

পরে:

এখানে চিত্র বর্ণনা লিখুন


ম্যাকোস সুইফট ৪.২ সংস্করণ: (এনএসএস স্ক্রিন.মাইন?
রবার্তো

17

প্রথমে আমি এটি চিহ্নিত করতে চেয়েছিলাম যে আপনি আপনার প্রশ্নটি আইওএসের সাথে ট্যাগ করেছেন, তবে সীমাবদ্ধতা পরিচালকরা কেবল ওএসএক্সে উপলব্ধ, সুতরাং আপনি নিশ্চিত না যে আপনি এটির বিরুদ্ধে লিঙ্ক করতে না পারলে আপনি কীভাবে এটি কাজ করতে চলেছেন? একরকম সিমুলেটারে ডিভাইসে, এই কার্যকারিতা উপলব্ধ নয়।

এরপরে, আমি কেবল উল্লেখ করব যে আমি প্রায়শই ক্যাটেক্সটায়ারগুলি তৈরি করি এবং আপনি যে ঝাপসা সমস্যাটি উল্লেখ করছেন তা কখনই না হয় তাই আমি জানি যে এটি করা যেতে পারে। সংক্ষেপে এই ঝাপসা দেখা দেয় কারণ আপনি পুরো পিক্সেলটিতে আপনার স্তরটি অবস্থান করছেন না। মনে রাখবেন যে আপনি যখন কোনও স্তরের অবস্থান সেট করেন, আপনি 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

ShouldRasterize সেট করার আগে আপনার উচিত:

  1. আপনি যে বেস স্তরটি চালিত করতে যাচ্ছেন তার রাস্টারাইজেশনস্কেল সেট করুন
  2. কোনও CATextLayers এর সামগ্রীর স্কেল সম্পত্তি এবং সম্ভবত অন্যান্য ধরণের স্তরগুলি সেট করুন (এটি কখনই ব্যথা করে না)

যদি আপনি # 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 টি কাজ করা উচিত, প্রথমটির উপরে উল্লিখিত ছিল:

ক্যাটেক্সটায়ার প্রসারিত করুন এবং রেটিনা ডিসপ্লেটি যথাযথভাবে সমর্থন করার জন্য অস্বচ্ছ এবং সামগ্রীসমূহ স্কেল বৈশিষ্ট্যগুলি সেট করুন, তারপরে পাঠ্যের জন্য অ্যান্টি অ্যালিজিং সক্ষম করুন nder

+ (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

ওএসএক্সে ক্যাটাটল লাইয়ারের জন্য যদি আপনি এখানে অনুরূপ সমস্যার সন্ধান করতে এসেছেন, অনেক প্রাচীরের মাথা ঠেকানোর পরে, আমি এইটি করে পরিষ্কার স্পষ্ট পাঠ্য পেয়েছি:

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];
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.