ios – 旋转后的CATextLayer模糊文本

ios – 旋转后的CATextLayer模糊文本,第1张

概述我有与 question有关的问题 我已经设置了contentsScale并且在该文本看起来很好但是如果我应用3d旋转变换,则文本模糊不清. 图片here 初始化代码 // init text textLayer_ = [CATextLayer layer]; … textLayer_.contentsScale = [[UIScreen mainScreen] scale 我有与 question有关的问题
我已经设置了contentsScale并且在该文本看起来很好但是如果我应用3d旋转变换,则文本模糊不清.

图片here

初始化代码

// init text    textLayer_ = [CATextLayer layer];    …    textLayer_.contentsScale = [[UIScreen mainScreen] scale];    // init body path    pathLayer_ = [CAShapeLayer layer];    …    [pathLayer_ addSublayer:textLayer_];

轮换代码

// make the mirror    pathLayer_.transform = CAtransform3DRotate(pathLayer_.transform,M_PI,1,0);    textLayer_.transform = CAtransform3DRotate(textLayer_.transform,0);    [textLayer_ setNeedsdisplay];

为了测试我在初始化期间单独旋转文本.

// init text    textLayer_ = [CATextLayer layer];    …    textLayer_.transform = CAtransform3DRotate(textLayer_.transform,0);    textLayer_.contentsScale = [[UIScreen mainScreen] scale];

文本可以旋转并保持清晰
图片here

解决方法 光栅化

这里可能发生的是它决定将textLayer渲染为像素.请注意0​​7000的警告:

When the value of this property is NO,the layer is composited directly into the destination whenever possible. The layer may still be rasterized prior to compositing if certain features of the compositing model (such as the inclusion of filters) require it.

因此,CATextLayer可能会突然决定进行栅格化.如果它是旋转图层的子图层,它决定栅格化.所以,不要让这种情况发生.

单面图层

这会将您带回导致反转文本的解决方案.您可以通过关闭文本图层上的doubleSIDed来防止这种情况.您的标志现在在远处是空白的,因此添加第二个文本图层,相对于第一个旋转180度.

声明两个文本图层:

@property (retain) CAShapeLayer *pathLayer;@property (retain) CATextLayer *textLayerFront;@property (retain) CATextLayer *textLayerBack;

然后,将它们初始化为单面,背面层旋转180度:

CAShapeLayer *pathLayer = [CAShapeLayer layer];// Also need to store a UIBezIErPath in the pathLayer.CATextLayer *textLayerFront = [CATextLayer layer];textLayerFront.doubleSIDed = NO;textLayerFront.string = @"Front";textLayerFront.contentsScale = [[UIScreen mainScreen] scale];CATextLayer *textLayerBack = [CATextLayer layer];textLayerBack.doubleSIDed = NO;// Eventually both sIDes will have the same text,but for demonstration purposes we will label them differently.textLayerBack.string = @"Back";// Rotate the back layer 180 degrees relative to the front layer.textLayerBack.transform = CAtransform3DRotate(textLayerBack.transform,0);textLayerBack.contentsScale = [[UIScreen mainScreen] scale];// Make all the layers siblings.  These means they must all be rotated independently of each other.// The layers can flicker if their Z position is close to the background,so move them forward.// This will not work if the main layer has a perspective transform on it.textLayerFront.zposition = 256;textLayerBack.zposition = 256;// It would make sense to make the text layers siblings of the path layer,but this seems to mean they get pre-rendered,blurring them.[self.layer addSublayer:pathLayer];[self.layer addSublayer:textLayerBack];[self.layer addSublayer:textLayerFront];// Store the layers constructed at this time for later use.[self setTextLayerFront:textLayerFront];[self setTextLayerBack:textLayerBack];[self setPathLayer:pathLayer];

然后,您可以旋转图层.只要您始终旋转相同的量,它们就会显示正确.

CGfloat angle = M_PI;self.pathLayer.transform = CAtransform3DRotate(self.pathLayer.transform,angle,0);self.textLayerFront.transform = CAtransform3DRotate(self.textLayerFront.transform,0);self.textLayerBack.transform = CAtransform3DRotate(self.textLayerBack.transform,0);

然后,您应该发现在文本保持清晰时可以将符号旋转到任意角度.

文本到路径

如果您确实需要以导致CATextLayer栅格化的方式 *** 作文本显示,还有另一种选择:将文本转换为UIBezIErPath表示.然后可以将其放在CAShapeLayer中.这样做需要深入研究核心文本,但结果是强大的.例如,你可以animate the text being drawn.

// - (UIBezIErPath*) bezIErPathWithString:(Nsstring*) string Font:(UIFont*) Font inRect:(CGRect) rect;// Requires CoreText.framework// This creates a graphical version of the input screen,line wrapped to the input rect.// Core Text involves a whole hIErarchy of objects,all requiring manual management.- (UIBezIErPath*) bezIErPathWithString:(Nsstring*) string Font:(UIFont*) Font inRect:(CGRect) rect;{    UIBezIErPath *combinedGlyphsPath = nil;    CGMutablePathref combinedGlyphsPathref = CGPathCreateMutable();    if (combinedGlyphsPathref)    {        // It would be easy to wrap the text into a different shape,including arbitrary bezIEr paths,if needed.        UIBezIErPath *frameShape = [UIBezIErPath bezIErPathWithRect:rect];        // If the Font name wasn't found while creating the Font object,the result is a crash.        // AvoID this by falling back to the system Font.        CTFontRef FontRef;        if ([Font Fontname])            FontRef = CTFontCreateWithname((__brIDge CFStringRef) [Font Fontname],[Font pointSize],NulL);        else if (Font)            FontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType,NulL);        else            FontRef = CTFontCreateUIFontForLanguage(kCTFontUserFontType,[UIFont systemFontSize],NulL);        if (FontRef)        {            CGPoint basePoint = CGPointMake(0,CTFontGetAscent(FontRef));            CFStringRef keys[] = { kCTFontAttributename };            CFTypeRef values[] = { FontRef };            CFDictionaryRef attributesRef = CFDictionaryCreate(NulL,(const voID **)&keys,(const voID **)&values,sizeof(keys) / sizeof(keys[0]),&kcfTypeDictionaryKeyCallBacks,&kcfTypeDictionaryValueCallBacks);            if (attributesRef)            {                CFAttributedStringRef attributedStringRef = CFAttributedStringCreate(NulL,(__brIDge CFStringRef) string,attributesRef);                if (attributedStringRef)                {                    CTFramesetterRef frameSetterRef = CTFramesetterCreateWithAttributedString(attributedStringRef);                    if (frameSetterRef)                    {                        CTFrameRef frameRef = CTFramesetterCreateFrame(frameSetterRef,CFRangeMake(0,0),[frameShape CGPath],NulL);                        if (frameRef)                        {                            CFArrayRef lines = CTFrameGetlines(frameRef);                            CFIndex lineCount = CFArrayGetCount(lines);                            CGPoint lineOrigins[lineCount];                            CTFrameGetlineOrigins(frameRef,lineCount),lineOrigins);                            for (CFIndex lineIndex = 0; lineIndex<lineCount; lineIndex++)                            {                                CTlineRef lineRef = CFArrayGetValueAtIndex(lines,lineIndex);                                CGPoint lineOrigin = lineOrigins[lineIndex];                                CFArrayRef runs = CTlineGetGlyphRuns(lineRef);                                CFIndex runcount = CFArrayGetCount(runs);                                for (CFIndex runIndex = 0; runIndex<runcount; runIndex++)                                {                                    CTRunRef runRef = CFArrayGetValueAtIndex(runs,runIndex);                                    CFIndex glyphCount = CTRunGetGlyphCount(runRef);                                    CGGlyph glyphs[glyphCount];                                    CGSize glyphAdvances[glyphCount];                                    CGPoint glyphpositions[glyphCount];                                    CFRange runRange = CFRangeMake(0,glyphCount);                                    CTRunGetGlyphs(runRef,glyphCount),glyphs);                                    CTRunGetpositions(runRef,runRange,glyphpositions);                                    CTFontGetAdvancesForGlyphs(FontRef,kCTFontDefaultOrIEntation,glyphs,glyphAdvances,glyphCount);                                    for (CFIndex glyphIndex = 0; glyphIndex<glyphCount; glyphIndex++)                                    {                                        CGGlyph glyph = glyphs[glyphIndex];                                        // For regular UIBezIErPath drawing,we need to invert around the y axis.                                        CGAffinetransform glyphtransform = CGAffinetransformMakeTranslation(lineOrigin.x+glyphpositions[glyphIndex].x,rect.size.height-lineOrigin.y-glyphpositions[glyphIndex].y);                                        glyphtransform = CGAffinetransformScale(glyphtransform,-1);                                        CGPathref glyPHPathref = CTFontCreatePathForGlyph(FontRef,glyph,&glyphtransform);                                        if (glyPHPathref)                                        {                                            // Finally carry out the appending.                                            CGPathAddpath(combinedGlyphsPathref,NulL,glyPHPathref);                                            CFRelease(glyPHPathref);                                        }                                        basePoint.x += glyphAdvances[glyphIndex].wIDth;                                        basePoint.y += glyphAdvances[glyphIndex].height;                                    }                                }                                basePoint.x = 0;                                basePoint.y += CTFontGetAscent(FontRef) + CTFontGetDescent(FontRef) + CTFontGetLeading(FontRef);                            }                            CFRelease(frameRef);                        }                        CFRelease(frameSetterRef);                    }                    CFRelease(attributedStringRef);                }                CFRelease(attributesRef);            }            CFRelease(FontRef);        }        // Casting a CGMutablePathref to a CGPathref seems to be the only way to convert what was just built into a UIBezIErPath.        combinedGlyphsPath = [UIBezIErPath bezIErPathWithCGPath:(CGPathref) combinedGlyphsPathref];        CGPathRelease(combinedGlyphsPathref);    }    return combinedGlyphsPath;}

这是旋转的轮廓文本,使用上面的方法创建.还可以在没有文本层的z位置变得明显的情况下添加透视.

总结

以上是内存溢出为你收集整理的ios – 旋转后的CATextLayer模糊文本全部内容,希望文章能够帮你解决ios – 旋转后的CATextLayer模糊文本所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1007142.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存