知识共享许可协议本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。本文仅作为个人学习记录使用,欢迎在许可协议范围内转载或使用,请尊重版权并且保留原文链接,谢谢您的理解合作。如果您觉得本站对您能有帮助,您可以使用RSS方式订阅本站,这样您将能在第一时间获取本站信息。

Start

cocoa drawing guide学习第三集~总算是写到第三集了啊,看来drawing guide的学习分享应该是能完成的,不过看了看目录貌似还有第四第五第六第七第八的-,-…慢慢来:)

上一期想了想,总觉得是自己再笨拙的翻译,不过后来想了想,看了看,想了想,再看了看,再想了想,觉得自己还是吧一些重要的东西找了出来,也顺着把guide走了一遍,要是只是选出重点,或者选出怎么用來,那就是Cookbook了,所以大家别嫌啰嗦啊,我也是跟着学的,哈哈,不罗嗦了,正片开始。

这一集的故事是颜色和透明的,用好色,用好透,那画出来的界面,肯定杠杠滴。

颜色和透明基础知识

Cocoa的颜色支持构建在Quartz的顶层,NSColor类提供了创建和操作颜色的接口,其他的类提供了颜色和颜色空间的管理,以及在UI上选择颜色的控件。

关于OS X里面的颜色解析,颜色理论和颜色管理,还要看看Color Management OverviewColor Programming Topics,-,-要看的东西真是越来越多了,也不知道看完能不能成cocoa大师啊。

颜色模型和颜色空间

颜色模型:用来描述可见色的几何或是数学的方法,每个颜色模型通过一个或多个维度来表示可见光光谱的颜色。维度上的数值使颜色可以通过数值来描述,使用数值为描述、区分、比较、排序颜色提供了方便。

上面这么长一段话,就是告诉我们,颜色模型是用数值来描述颜色的。

颜色空间:颜色空间是用来描述颜色模型的,确定一个颜色模型实际能够表示的色域,颜色空间明确颜色模型的每个维度的值所表示的是什么。Cocoa支持的颜色空间和Quartz 2D的颜色空间一样,NSColor的访问方法支持:RGB、CMYK、Gray(灰度)这几种颜色空间。

上面这长短话,就是说,颜色空间就是颜色模型里面用的是RGB啦,还是CMYK啦,还是灰度啦之类的。

Cocoa里面NSColorSpace类保存描述具体颜色空间的信息,我们可以自行创建NSColorSpace的对象来表示独立的颜色空间,Cocoa提供了给我们获取标准颜色空间对象的方法,我们也可以用ColorSync的描述文件或者International Color Consortium (ICC)的描述文件来创建自定义颜色空间。

更详细的OS X颜色模型和颜色空间参看Color Management Overview

颜色对象

NSColor提供了创建管理颜色的接口,并且他是创建颜色对象的工厂类,他的类方法创建的颜色对象都是基于NSColor的子类,并且这些子类都实现了特定颜色空间的行为。

一个颜色对象只能表示一种颜色空间的颜色,所以不能使用NSColor一个对象的所有方法,只能使用跟他的颜色空间相关的方法,比如在CMYK颜色空间下的一个颜色对象就不能使用getRed:green:blue:alpha:方法获取RGB值,在CMYK颜色空间不支持这个方法,并且会产生异常。

下面创建颜色会讲怎么创建和使用颜色对象。

颜色构成的值

颜色构成使用从0.0到1.0的浮点数表示,使用其他颜色系统的颜色的时候需要进行转换,比如用的颜色值从0到255的话,那么每个值都需要除以255才是Cocoa所使用的值。

对于已知颜色空间(比如RGB,CMYK,HSV/HSB或者灰度)之类的颜色空间,我们可以通过现成的方法获取颜色成分(比如刚才的getRed:green:blue:alpha:方法),对于颜色成分未知的可以通过numberOfComponentsgetComponents:方法获取颜色成分值。

透明度

除了表示颜色的成分意外,还有表示透明度的颜色成分。可以使用colorWithAlphaComponent:方法创建一个颜色相同但是透明度不同的颜色。

图案颜色

除了单一的颜色以外我们还可以创建图案颜色,图案颜色很多时候用来作为填充色,当然也可以作为描边的颜色。如果图案不够填充整个形状,那么他就会横向和纵向的平铺,如下图:

使用图案颜色绘图

怎个用?下面创建颜色会讲滴。

颜色列表

NSColorList对象是一个类似于Dictionary的对象,保存一个按顺序的颜色对象列表,并且使用键值来索引。

颜色列表可以用来帮助管理文档描述的颜色,也可以用来自定义显示在调色板中的颜色,可以使用NSColorPanelattachColorList:方法添加颜色到应用程序里面用的调色盘中。

详情可以看看Color Programming Topics

颜色匹配

在可以使用ColorSync的情况下Cocoa提供了自动的颜色匹配,颜色匹配确保了绘制颜色在不同的设备上保持一致。

通过NSColorSpace类可以创建或是获取颜色描述,Cocoa支持ColorSync和ICC的颜色描述以及对他们校准后的描述,和设备上RGB,CMYK,灰度颜色空间。颜色匹配是自动的,所以除了使用颜色以外,代码没有任何特殊的地方。

关于ColorSync可以参考ColorSync Manager Reference,关于ICC可以参考http://www.color.org/

创建颜色

NSColor支持下面几种方法创建颜色对象:

  • 通常使用的RGB或者白色度
  • 系统颜色,例如控件的颜色、高亮的颜色等
  • 特定颜色空间校准后的颜色
  • 特定设备颜色空间下的设备颜色
  • 图案颜色

大多数颜色对象都可以直接用NSColor中的方法来创建,创建图案颜色可以使用colorWithPatternImage:方法。如何创建加载方法可以看后面part,Image那部分。

注意:不要[[NSColor alloc] init]这种方法来创建颜色,因为NSColor至少需要知道具体的颜色信息,否则他就会出异常。

OS X 10.5后支持使用渐变填充色,10.5之前如果需要使用渐变色,需要使用Quartz,如何使用的话,详看后面的创建渐变填充。

使用颜色

使用NSColor对象可以用来作为当前绘图上下文的填充色或是描边色。

在绘制的内容上使用颜色

描边色和填充色用来修改所有基于路径的形状,例如NSBezierPath或者NSRectFillNSColor的下面方法提供了对颜色的设置:

  • set:设置描边色和填充色
  • setFill:设置填充色
  • setStroke:设置描边色

例如下面的代码用黑色作为描边色,控件背景色作为填充色:

[[NSColor blackColor] setStroke];
[[NSColor controlBackgroundColor] setFill];

设置颜色之后所有的绘图操作都会使用,如果你不想要绘制形状的填充色或是描边色的话,可以把他们设为全透明,或者调用NSColorclearColor方法,也可以创建一个全透明的颜色。

注意:这里设置填充色和描边色不会对文字造成影响,文字的颜色需要设置文字所关联的属性。

在文字上使用颜色

文字不会使用填充色或是描边色,修改文字的颜色需要调整对应字符串的颜色属性。

修改NSAttributedString中一部分字符串的颜色,需要对字符串应用NSForegroundColorAttributeName属性,这个属性需要传入一个确定的NSColor对象。对于NSString的话,则是应用到整个字符串,而不是一部分字符串。

更多的关于字符串属性的东西可以参考AppKit Framework Reference中的NSAttributedString Application Kit Additions ReferenceAttributed String Programming Guide中的Changing an Attributed String。更多关于文字绘制的信息,可以看后面几个部分。

获取颜色的颜色组成

NSColor除了提供获取单独部分颜色组成的方法,也提供下面的方法获取颜色组成:

  • numberOfComponents
  • getComponents:
  • getRed:green:blue:alpha:
  • getCyan:magenta:yellow:black:alpha:
  • getHue:saturation:brightness:alpha:
  • getWhite:alpha:

注意:使用NSColor对象的方法获取非颜色对象所在颜色空间的颜色组成是不可以的,如果要用,必须使用colorUsingColorSpaceName:方法先进行颜色空间转换,详看下面的在颜色空间中相互转换。

选择颜色

可以使用Color Well或者Color Panel提供给用户选择颜色,一个Color Well显示一个颜色可以用来放在窗体上显示当前所选的颜色,单击Color Well的时候显示系统的Color Panel作为选取颜色的界面。也可以只使用Color Panel提供给用户选取颜色。

详情参考Color Programming Topics

使用颜色空间

颜色空间可以让我们能够在创建和渲染的过程中精确控制颜色,尽管大多数的应用基本上不需要关注颜色空间,但是在操作颜色成分之前等一些情况,我们还是需要知道当前的颜色空间的。

在颜色空间中相互转换

可以使用NSColorcolorUsingColorSpaceName:方法进行颜色空间的转换,下面代码把RGB颜色空间的颜色转换到了CMYK颜色空间。

NSColor* rgbColor = [NSColor colorWithCalibratedRed:1.0 green: 0.5  blue: 0.5  alpha:0.75];

NSColor* cmykColor = [rgbColor colorUsingColorSpace:[NSColorSpace  genericCMYKColorSpace]];

将物理颜色映射到颜色空间

不同的设备显示颜色范围是不同的,渲染的时候,cocoa将尽可能的根据你的代码匹配颜色到具体的设备上。有时候尽管为了强调一个颜色的不同部分而使用不同的方法映射颜色,那么那个颜色的衍生就非常的重要。(其实这句我看的翻译的感觉都不是太好,莺语没学好啊,附原文Sometimes, though, it maps colors in a different way so as to emphasize different aspects of a color that might be more important when reproducing that color.)颜色的映射也就是如何渲染,这个对大多数开发人员来说是基本不会去修改的,因此,我们也不能直接通过cocoa来修改,只能通过Quartz,下面是Quartz提供的方法:

  • kCGRenderingIntentDefault
  • kCGRenderingIntentAbsoluteColorimetric
  • kCGRenderingIntentRelativeColorimetric
  • kCGRenderingIntentPerceptual
  • kCGRenderingIntentSaturation

基本用不到具体不详看了,偷下懒:P,不过下面我们还是来看看具体怎么来改变渲染方式,通过CGContextSetRenderingIntent方法:

- (void) drawRect:(NSRect)rect
{
    CGContextRef theCG = [[NSGraphicsContext currentContext] graphicsPort];

    // Change the rendering intent.
    CGContextSetRenderingIntent(theCG, kCGRenderingIntentPerceptual);

    // Draw your content.
}

end

本期结束鸟~~这一期关注点在颜色上,再看果然Apple对于颜色,绘图这些方面是做了苦工的啊,而且确实很强力。

P.S. 大减价的时候买了个PaintCode发现这货完全就是一个大杀器啊,这几天的博客都白写了,就靠那东西,基本搞定所有绘制的问题了。。。不过还是继续看了,毕竟还是需要知其所以然方能收放自如:P

最后欢迎大家订阅我的微信公众号 Little Code

公众号

  • 公众号主要发一些开发相关的技术文章
  • 谈谈自己对技术的理解,经验
  • 也许会谈谈人生的感悟
  • 本人不是很高产,但是力求保证质量和原创