Core Graphics 一: CGContext基本绘制
Core Graphics 二: CGAffineTransform变换和CTM坐标系
Core Graphics 三: CGPath
一.色彩和色彩空间
电磁波有不同的波长,一定范围内波长的电磁波会被人眼感受到,这部分就是可见光,光源或者物体反射可见光被人眼接受到,就会被大脑解析为对色彩的感知.但是一束电磁波里包含了各种波段,一束可见光也是,混合起来会产生多种多样的色彩.
什么是加减色.三个手电筒,每个手电筒上都装有一个彩色的透明滤波片,颜色分别是红、绿和蓝,然后将光投射到墙上,两个手电筒圈的交叠部分比任何一个单个圈都要亮,而三个圈中间的交叠部分更亮,每种混合,都会增加亮度,因此这种混合光我们称之为加色光.
加色
而减色指的是颜料等着色剂产生的混合效果,颜料在混合中,其波长的光线会被吸收而造成一定的颜色混合,从而出现其他颜色.
描述色彩的模型叫做色彩空间,如RGB,HSB,HSV,HLS等.
-
RGB空间
RGB空间表示的颜色是三种原色的某种混合:红色,绿色和蓝色.可以显示为一个立方体.
RGB空间
-
HSV和HLS空间
H(hue),色相/色调,即光的波长.不同波长的光直观的被人眼感知成各种颜色
S(Saturation),饱和度/灰度,即色彩的浓度,或者说色彩中的灰色成分多少,饱和度越高,灰色越少,色彩越浓郁
V(Value),亮度/明度,即色彩的亮度,或者说白色成分的多少,值越高,则越亮,直到纯白,反之越暗,直到纯黑
HSV -
CMY空间
基于CMY的色彩空间最常用于彩色打印系统中。它们本质上是依赖于设备且相减的。CMY系列中的颜色空间组包括CMY,除了低端彩色打印机以外,这不是很常见;CMYK,模拟油墨或染料在打印纸上的应用方式.
名称CMYK表示青色,洋红色,黄色和键(以黑色表示)。青色,品红色和黄色是此颜色空间中的三个原色,红色,绿色和蓝色是三个第二色。从理论上讲,不需要黑色。但是,当全饱和度的青色,品红色和黄色墨水在纸张上混合均匀时,结果通常是深棕色而不是黑色。因此,黑色墨水会在较暗的区域套印,以扩大动态范围并提供更好的外观。使用黑色墨水进行打印可以减少使用青色,品红色和黄色墨水。这可以防止饱和,尤其是在不能接受过多墨水的普通纸等材料上。使用黑色还可以降低每页成本,因为青色,品红色和黄色墨水通常比黑色墨水贵。它还可以提供更清晰的图像.
CMY
1.CGColor
-
CGColorRef CGColorGetConstantColor(CFStringRef colorName);
返回一个CGColorRef,colorName是一个常量,只有kCGColorWhite, kCGColorBlack, kCGColorClear三个值 -
CGColorRef CGColorCreateGenericGray(CGFloat gray, CGFloat alpha);
生成一个灰色,gray是灰度,0.0-1.0,1.0是白色,0.0是黑色,alpha是透明度
-
CGColorRef CGColorCreateGenericRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
根据RGB空间生成颜色,参数范围都是0.0-1.0 -
CGColorRef CGColorCreateSRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
同上,根据sRGB生成
RGB和sRGB两个方法生成的颜色不一样,同样是(.1, .5, .5, 1),上面是sRGB,下面是RGB
image.png
-
CGColorRef CGColorCreateGenericCMYK(CGFloat cyan, CGFloat magenta, CGFloat yellow, CGFloat black, CGFloat alpha);
根据CMYK空间生成颜色 -
CGColorRef CGColorCreateCopyWithAlpha(CGColorRef color, CGFloat alpha);
修改颜色的透明度 -
CGFloat CGColorGetAlpha(CGColorRef color);
获取颜色透明度
2.color space 色彩空间
在core Graphics中colorSpace主要有设备无关色彩空间,设备色彩空间和通用色彩空间,创建设备无关的色彩空间需要提供很多参数,涉及比较专业的内容,创建设备色彩空间和通用色彩空间基本不需要参数,直接create例如CGColorSpaceCreateDeviceCMYK; CGColorSpaceCreateDeviceGray; CGColorSpaceCreateDeviceRGB
- CGColorSpaceRef CGColorSpaceCreateWithName(CFStringRef name);
根据名字创建色彩空间,这里Apple提供了很多种Color Space Names
- void CGContextSetFillColorSpace(CGContextRef c, CGColorSpaceRef space);
- void CGContextSetStrokeColorSpace(CGContextRef c, CGColorSpaceRef space);
这两个方法是给上下文设置色彩空间,给上下文设置颜色已经在第一篇讲过
二.渐变Gradient
首先创建一个渐变
- CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef space, const CGFloat *components, const CGFloat *locations, size_t count);
space是色彩空间
components是描述颜色的变化,需要依据space来设置,比如space是RBG或者sRGB,那么components就需要是RGBA四个参数,并且因为是渐变,所以至少需要两个RBGA也就是8个浮点数
locations是每个RGBA起效的位置,范围是0.0-1.0,比如components是12个浮点数,描述了三个颜色ABC,location是[.0,.5,1.0],那么前一半是A到B渐变,后一半是B到C渐变.
count是location的长度
CGGradientRef myGradient;
CGColorSpaceRef myColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 0.5, 0.4, 1.0, 0.8, 0.8, 0.3, 1.0 };
myColorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
myGradient = CGGradientCreateWithColorComponents (myColorspace, components, locations, num_locations);
- CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, CFArrayRef colors, const CGFloat *locations);
colors是一个CGColor的数组
其他与上一个函数相同,
CGColorRef colors[] = {UIColor.whiteColor.CGColor,UIColor.blackColor.CGColor};
CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, (void *)colors, (CFIndex)2, NULL);
CGGradientRef myGradient2 = CGGradientCreateWithColors(myColorspace, array, locations);
创建渐变之后,在上下文绘制
- void CGContextDrawLinearGradient(CGContextRef c, CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions options);
线性渐变,提供两个点,形成一条线A,整个画布看成和线A平行的无数条线,每条线都按照A去做渐变
CGPoint myStartPoint, myEndPoint;
myStartPoint.x = 0;
myStartPoint.y = 0;
myEndPoint.x = rect.size.width;
myEndPoint.y = 0;
CGContextDrawLinearGradient (UIGraphicsGetCurrentContext(), myGradient2, myStartPoint, myEndPoint, 0);
image.png
- void CGContextDrawRadialGradient(CGContextRef c, CGGradientRef gradient, CGPoint startCenter, CGFloat startRadius, CGPoint endCenter, CGFloat endRadius, CGGradientDrawingOptions options);
双圆心渐变,提供两个圆心,和两个半径
CGPoint myStartPoint, myEndPoint;
myStartPoint.x = 0;
myStartPoint.y = rect.size.height / 2;
myEndPoint.x = rect.size.width;
myEndPoint.y = rect.size.height / 2;
CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(), myGradient, myStartPoint, rect.size.height/2,
myEndPoint, rect.size.height/2, kCGGradientDrawsAfterEndLocation);
image.png
三.图案pattern
关于pattern官方文档说明的更清晰
pattern是一系列绘制操作,重复绘制到图形上下文。 您可以使用与使用颜色相同的方式使用模式。 当您使用pattern进行绘制时,Quartz将页面划分为一组pattern单元格,每个单元格都是图案pattern图像的大小,并使用您提供的回调绘制每个单元格.
简单的理解,pattern就像一块布上的花纹或者说图案,它是重复平铺的,单元格之间的距离可以设置.
image.png
图案(pattern)可以直接填充上下文,也可以生成color.
直接使用CGPatternCreate创建需要一大堆的参数,下面来解释一下使用方法
CGPatternRef CGPatternCreate ( void *info,
CGRect bounds,
CGAffineTransform matrix,
CGFloat xStep,
CGFloat yStep,
CGPatternTiling tiling,
bool isColored,
const CGPatternCallbacks *callbacks );
- info参数是指向要传递给绘图回调的数据的指针.
- bounds指定图案单元格的bounds.
- matrix是单元格的2d变换,不需要的话可以设置为单位矩阵CGAffineTransformIdentity
- xStep和yStep参数指定图案坐标系中单元格之间的水平和垂直间距
- tiling是平铺样式
- isColored是否彩色
- callbacks 绘制单元格的函数
void customPattern (void *info, CGContextRef myContext)
{
CGFloat subunit = 20;
CGRect myRect1 = {{0,0}, {subunit, subunit}},
myRect2 = {{subunit, subunit}, {subunit, subunit}},
myRect3 = {{0,subunit}, {subunit, subunit}},
myRect4 = {{subunit,0}, {subunit, subunit}};
CGContextSetRGBFillColor (myContext, 0, 0, 0, 1);
CGContextFillRect (myContext, myRect1);
CGContextSetRGBFillColor (myContext, 0, 0, 0, 1);
CGContextFillRect (myContext, myRect2);
CGContextSetRGBFillColor (myContext, 1, 1, 1, 1);
CGContextFillRect (myContext, myRect3);
CGContextSetRGBFillColor (myContext, 1, 1, 1, 1);
CGContextFillRect (myContext, myRect4);
}
void painting (CGContextRef myContext,
CGRect rect)
{
CGPatternRef pattern;
CGColorSpaceRef patternSpace;
CGFloat alpha = 1;
static const CGPatternCallbacks callbacks = {0,
&customPattern,
NULL};
CGContextSaveGState (myContext);
patternSpace = CGColorSpaceCreatePattern (NULL);
CGContextSetFillColorSpace (myContext, patternSpace);
CGColorSpaceRelease (patternSpace);
pattern = CGPatternCreate (NULL,
CGRectMake (0, 0, 40, 40),
CGAffineTransformRotate(CGAffineTransformIdentity, M_PI_4),
50,
50,
kCGPatternTilingConstantSpacing,
true,
&callbacks);
CGContextSetFillPattern (myContext, pattern, &alpha);
CGPatternRelease (pattern);
CGContextFillRect (myContext, rect);
CGContextRestoreGState (myContext);
}
- (void)drawRect:(CGRect)rect{
CGContextRef context = UIGraphicsGetCurrentContext();
painting(context, rect);
}
1.void customPattern (void *info, CGContextRef myContext)是绘制单元格的回调函数
2.这里不需要info,所以传了NULL
3.用pattern来填充上下文,使用CGContextSetFillPattern或者CGContextSetStrokePattern
绘制出来的效果
网友评论