Cocoa - 绘制渐进色文字

Cocoa - 绘制渐进色文字,第1张

概述CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; CGContextSaveGState(context); CGContextTranslateCTM(context, 0.0f, self.bounds.size.height); CGContextScaleCTM(con

CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];    CGContextSaveGState(context);    CGContextTranslateCTM(context,0.0f,self.bounds.size.height);    CGContextScaleCTM(context,1.0f,-1.0f);        CGContextSelectFont(context,"Helvetica",20.0f,kCGEnCodingMacRoman);    CGContextSetTextDrawingMode(context,kCGTextClip);    CGContextSetTextposition(context,round(20.0f / 4.0f));    //这个函数不能显示中文。。。。    CGContextshowtext(context,[_content UTF8String],strlen([_content UTF8String]));        CGContextClip(context);        CGGradIEntRef gradIEnt;    CGcolorSpaceRef rgbcolorspace;    size_t num_locations = 2;    CGfloat locations[2] = { 0.0,1.0 };    CGfloat components[8] = { 1.0,1.0,// Start color        1.0,0.1 }; // End color        rgbcolorspace = CGcolorSpaceCreateDeviceRGB();    gradIEnt = CGGradIEntCreateWithcolorComponents(rgbcolorspace,components,locations,num_locations);        CGRect currentBounds = self.bounds;    CGPoint topCenter = CGPointMake(CGRectGetMIDX(currentBounds),0.0f);    CGPoint mIDCenter = CGPointMake(CGRectGetMIDX(currentBounds),CGRectGetMIDY(currentBounds));    CGContextDrawlinearGradIEnt(context,gradIEnt,topCenter,mIDCenter,0);        CGGradIEntRelease(gradIEnt);    CGcolorSpaceRelease(rgbcolorspace);        CGContextRestoreGState(context);

上面这段代码使用Core Graphics来绘制渐渐色文字,但是有个致命的缺点:CGContextshowtext 这个方法不能显示Unicode 编码的文字,因此也无法显示中文。

Core Graphics 这套API中只有CGContextshowtext 这个显示文字的方法,所以不得不改用其他的方案。后来,发现了一个比较取巧的解决办法:
渐进色绘制到空白的图片(Bitmap)上,然后调用 
+ (NScolor *)colorWithPatternImage:(NSImage*)image;   ,传入上面生成的图片,即可得到颜色值,将得到的颜色值设给文字的NSForegroundcolorAttributename 属性。下面来看看具体实现的代码。

将通过渐渐色生成NSImage这些逻辑写在了 NSImage+GradIEnt 这个类中,NSImage+GradIEnt.m 实现如下:

#import "NSImage+GradIEnt.h"@implementation NSImage (GradIEnt)/** * @method * @abstract 生成渐进色背景图片 * @discussion  * @param gradIEntcolors 渐进色数组  imageSize:要生成的图片的大小 * @result NSImage :返回生成的图片 */+ (NSImage *)gradIEntimageWithcolors:(NSArray *)gradIEntcolors imageSize:(NSSize)imageSize {    if (gradIEntcolors == nil || NSEqualSizes(imageSize,NSZeroSize)) {        return nil;    }        NSBitmAPImageRep * bitmapRep = nil;    NSImage *image = nil;        if (imageSize.wIDth > 0 && imageSize.height > 0) {                int pixelsWIDe = imageSize.wIDth,pixelsHigh = imageSize.height;         CGContextRef ctx = NulL;                bitmapRep = [[NSBitmAPImageRep alloc] initWithBitmapDataPlanes: nil  // Nil pointer makes the kit allocate the pixel buffer for us.                                                            pixelsWIDe: pixelsWIDe  // The compiler will convert these to integers,but I just wanted to  make it quite explicit                                                            pixelsHigh: pixelsHigh //                                                         bitsPerSample: 8                                                       samplesPerPixel: 4  // Four samples,that is: RGBA                                                              hasAlpha: YES                                                              isPlanar: NO  // The math can be simpler with planar images,but performance suffers..                                                        colorSpacename: NSCalibratedRGBcolorSpace  // A calibrated color space gets us colorSync for free.                                                           bytesPerRow: pixelsWIDe * 4                                                               bitsPerPixel: 32];  // This must agree with bitsPerSample and samplesPerPixel.;                if (bitmapRep) {            ctx = CGBitmapContextCreate([bitmapRep bitmapData],[bitmapRep size].wIDth,[bitmapRep size].height,[bitmapRep bitsPerSample],[bitmapRep bytesPerRow],[[bitmapRep colorSpace] CGcolorSpace],kCGImageAlphaPremultiplIEdLast);        }                if (ctx) {            CGContextSaveGState(ctx);            //draw gradIEnt                CGGradIEntRef gradIEnt;            CGcolorSpaceRef rgbcolorspace;                        //set uniform distribution of color locations            size_t num_locations = [gradIEntcolors count];            CGfloat locations[num_locations];            for (int k=0; k<num_locations; k++) {                locations[k] = k / (CGfloat)(num_locations - 1); //we need the locations to start at 0.0 and end at 1.0,equaly filling the domain            }                        //create c array from color array            CGfloat components[num_locations * 4];            for (int i=0; i<num_locations; i++) {                NScolor *color = [gradIEntcolors objectAtIndex:i];                //                NSAssert(color.canProvIDeRGBComponents,@"color components Could not be extracted from StyleLabel gradIEnt colors.");                components[4*i+0] = [color redComponent];                components[4*i+1] = [color greenComponent];                components[4*i+2] = [color blueComponent];                components[4*i+3] = [color AlphaComponent];            }                        rgbcolorspace = CGcolorSpaceCreateDeviceRGB();            gradIEnt = CGGradIEntCreateWithcolorComponents(rgbcolorspace,num_locations);            CGPoint topCenter = CGPointMake(0,0);            CGPoint bottomCenter = CGPointMake(0,imageSize.height);            CGContextDrawlinearGradIEnt(ctx,bottomCenter,0);                        CGGradIEntRelease(gradIEnt);            CGcolorSpaceRelease(rgbcolorspace);                         // pop context             CGContextRestoreGState(ctx);							        }                if (ctx) {            CGContextRelease(ctx); ctx = nil;        }    }        if (bitmapRep) {        image = [[NSImage alloc] initWithData:[bitmapRep TIFFRepresentation]];        [bitmapRep release]; bitmapRep = nil;    }        return [image autorelease];}@end

 然后,定义了NSVIEw的一个子类用来绘制和显示渐渐色文字。
MyGradIEntTextVIEw.h
#import <Cocoa/Cocoa.h>@interface MyGradIEntTextVIEw : NSVIEw {    Nsstring *_content;        NSMutableDictionary *_textAttr;}- (voID)setContent:(Nsstring *)content;@end

MyGradIEntTextVIEw.m

#import "MyGradIEntTextVIEw.h"#import "NSImage+GradIEnt.h"@implementation MyGradIEntTextVIEw- (ID)initWithFrame:(NSRect)frame{    self = [super initWithFrame:frame];    if (self) {        _textAttr = [[NSMutableDictionary alloc] init];        //LucIDa Grande        [_textAttr setValue:[NSFont FontWithname:@"HelveticaNeue-Bold" size:75] forKey:NSFontAttributename];        [_textAttr setValue:[NScolor greencolor] forKey:NSForegroundcolorAttributename];//        [_textAttr setValue:[NSNumber numberWithfloat:-1] forKey:NSstrokeWIDthAttributename];//轮廓宽度        [_textAttr setValue:[NScolor blackcolor] forKey:NSstrokecolorAttributename];//轮廓颜色                NSShadow *shadow = [[NSShadow alloc] init];        [shadow setShadowcolor: [NScolor blackcolor]];        [shadow setShadowBlurRadius: 1];        [shadow setShadowOffset: NSMakeSize( 0,-1)];        [_textAttr setValue:shadow forKey:NSShadowAttributename];        [shadow release];                NSMutableParagraphStyle* paraStyle = [[NSMutableParagraphStyle alloc] init];        [paraStyle setAlignment:NSCenterTextAlignment];        [paraStyle setlineBreakMode:NSlineBreakByWorDWrapPing];        [_textAttr setValue:paraStyle forKey:NSParagraphStyleAttributename];        [paraStyle release];    }        return self;}- (voID)dealloc{    [_content release];    [_textAttr release];    [super dealloc];}- (voID)drawRect:(NSRect)dirtyRect{    if (_content) {        NSSize textSize = [_content sizeWithAttributes:_textAttr];	//自己可根据需要来配置颜色数组        NSArray *colorArray = [NSArray arrayWithObjects:                      [NScolor colorWithDeviceRed:255/255.0 green:128/255.0 blue:0/255.0 Alpha:1.0],[NScolor colorWithDeviceRed:255/255.0 green:210/255.0 blue:79/255.0 Alpha:1.0],[NScolor colorWithDeviceRed:140/255.0 green:198/255.0 blue:63/255.0 Alpha:1.0],nil];        //关键在这里了        NSImage *graIDentimage = [NSImage gradIEntimageWithcolors:colorArray imageSize:textSize];        NScolor *textcolor = [NScolor colorWithPatternImage:graIDentimage];                [_textAttr setValue:textcolor forKey:NSForegroundcolorAttributename];                NSRect drawRect = NSMakeRect(NSMinX(self.bounds),NSMinY(self.bounds),textSize.wIDth,textSize.height);        [_content drawInRect:drawRect withAttributes:_textAttr];    }}- (voID)setContent:(Nsstring *)content {    [content retain];    [_content release];    _content = content;        [self setNeedsdisplay:YES];}@end

最后,绘制出来的效果如下:


完整代码: DrawGradientText


总结

以上是内存溢出为你收集整理的Cocoa - 绘制渐进色文字全部内容,希望文章能够帮你解决Cocoa - 绘制渐进色文字所遇到的程序开发问题。

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

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存