iOS绘图
相关的framework
iOS里面公开的,几个绘图有关的framework之间的关系
CoreGraphics.framework Quartz 2D api manages the grahpic context and imp drawing,pdf
QuartzCore.framework api to do 2D animation,CALayer在这里定义。
CoreImage.framework 图片处理
CG 和 UI 坐标系变换
sh
CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
CGAffineTransformTranslate(transform, 0, -self.bounds.size.height);
self.transform = transform;
获取上下文
```oc UIKit的代码并没有传递context,UIKit维护着一个context栈 - (void)drawRect:(CGRect)rect UIGraphicsGetCurrentContext()
UIKit 创建一个位图context:
UIGraphicsBeginImageContext(zise)
UIGraphicsBeginImageContextWithOptions()
UIGraphicsEndImageContext() 结束绘画任务
CGBitmapContextCreate() 创建位图context CGContextRelease() 释放
CGBitmapContextCreateImage(context) CGImageRelease() 释放
```
UIKit和Core Graphics可以在相同的图形上下文中混合使用, setNeedsDisplay来更新视图,而不是直接调用drawRect;
为了提高一些绘图性能,你可以调用setNeedsDisplayInRect方法重新绘制视图的子区域,而视图的其他部分依然保持不变。
上下文状态保存
oc
CGContextSaveGState()
CGContextRestoreGState()
在上下文struct中维护一个栈结构来来保存上下文状态,我们在绘图时,可以保存当前的graphics state,到后面绘制的时候还可以使用这个状态,使用CGContextRestoreGState()将堆栈顶部的状态弹出,返回到之前的图形状态,避免逐个修改状态。
颜色空间
ARGC (32bit)
xRGB (32bit)没有alpha 通道,100%不透明,但是没有去掉alpha 通道的值,虽然可以节省25%空间,这是因为32字节对齐 更适合现在cpu和图形算法。
颜色空间的操作函数
CGColorRef、 CGColorSpaceRef
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorSpaceGetNumberOfComponents(colorSpace)
CGColorSpaceRelease(colorSpace);
操纵上下文状态的函数
包括设置线条宽度,线条颜色(stroke color),填充色(fill color),阴影颜色等,在每次绘制任务之前都可以设置下这些状态,否则使用上次设置过的状态。
```oc 线条的宽度和线条的虚线样式 CGContextSetLineWidth、CGContextSetLineDash
线条颜色和线条模式 CGContextSetRGBStrokeColor、CGContextSetGrayStrokeColor、CGContextSetStrokeColorWithColor、CGContextSetStrokePattern
线帽和线条联接点样式 CGContextSetLineCap、 CGContextSetLineJoin、 CGContextSetMiterLimit
填充颜色和模式 CGContextSetRGBFillColor,CGContextSetGrayFillColor,CGContextSetFillColorWithColor, CGContextSetFillPattern
阴影 CGContextSetShadow、CGContextSetShadowWithColor 参数解释:CGSize的两个值都是正数,则表示阴影是朝下和朝右的。模糊度被表示为任何一个正数。苹果没有解释缩放的工作方式,但实验表明12是最佳的模糊度,99及以上的模糊度会让阴影变得不成形。
混合模式 CGContextSetBlendMode(决定你当前绘制的图形与已经存在的图形如何被合成) ?
整体透明度 CGContextSetAlpha(个别颜色也具有alpha成分)
文本属性 CGContextSelectFont、CGContextSetFont、CGContextSetFontSize、CGContextSetTextDrawingMode、CGContextSetCharacterSpacing
是否开启反锯齿和字体平滑 CGContextSetShouldAntialias、CGContextSetShouldSmoothFonts ```
线条绘制函数—线条包括直线和曲线
```oc 定位当前点,然后描画一条线 CGContextMoveToPoint、CGContextAddLineToPoint CGContextAddLines() 指定一组点绘制一组线段
描画一个/一组矩形 CGContextAddRect、CGContextAddRects
描画一个椭圆或圆形 CGContextAddEllipseInRect
描画一段圆弧 CGContextAddArcToPoint void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y, CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise) x,y是圆弧的中心点,clockwise 为0表示顺时针,1表示逆时针 (文档里写的是:为1表示顺时针,0表示逆时针)
通过一到两个控制点描画一段贝赛尔曲线 CGContextAddQuadCurveToPoint() 参数是一个control point和一个end point。control point 到current point和 end point的2条直线都应该是这个曲线的切线。 如: CGContextMoveToPoint(context, 120, 300); CGContextAddQuadCurveToPoint(ctx,190, 310, 120, 390);
oid CGContextAddCurveToPoint(CGContextRef c, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y) 参数带有2个控制点,
关闭当前路径 CGContextClosePath 这将从路径的终点到起点追加一条线。如果你打算填充一段路径,那么就不需要使用该命令,因为该命令会被自动调用。 ```
绘图区域控制
矩形rect区域控制
oc
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);
CGRectInset(bounds, 20.0f, 0) 用这个做相对布局计算
描边或填充当前路径
CGContextStrokePath、CGContextFillPath、CGContextEOFillPath、CGContextDrawPath。对当前路径描边或填充会清除掉路径。如果你只想使用一条命令完成描边和填充任务,可以使用CGContextDrawPath命令,因为如果你只是使用CGContextStrokePath对路径描边,路径就会被清除掉,你就不能再对它进行填充了。
CGContextClearRect函数擦除一个区域
CGContextClearRect 擦除区域内的颜色,如果上下文是透明或有一点透明度,擦除后透明,否则(也就是完全不透明)擦除后为黑色
区域裁剪
CGContextClip 把接下来的绘制都限制在上面的绘图区域。我们可以绘制一个任意形状的裁剪区域,然后将源图绘制在裁剪区域完成区域裁剪,也即完成图片裁剪。
CGContextClipToRect()
遮罩mask
遮罩的用处
创建遮罩的方法
使用遮罩
CGContextClipToMask()
CGPath 复用一些路径和形状
oc
CGPathCreateMutable()
CGPathCreateWithRect() rect==> CGPath
CGPathCreateWithEllipseInRect()
CGPathAddRect()
CGContextAddPath(context, path);
UIBezierPath
封装了CGPath,提供一些类的方法来完成上面的操作:绘制某种形状路径(如圆角矩形),描边,填充,以及设置context 状态的方法。eg:
```sh UIBezierPath *bezierPath = [UIBezierPath bezierPath]; [bezierPath moveToPoint:[self convertPoint:firstButton.center fromView:self.contentView]]; [bezierPath addLineToPoint:[self convertPoint:button.center fromView:self.contentView]];
[bezierPath setLineWidth:self.lineWidth]; [bezierPath setLineJoinStyle:kCGLineJoinRound]; [self.lineColor setStroke]; [bezierPath stroke];
api: - (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint; 返回一条曲线
```
绘制渐变gradient
绘制有渐变色的线条
CGContextDrawLinearGradient
绘制渐变区域 CAGradientLayer CGGradientRef
绘制阴影shadow
CTM 上下文变换
CGContextTranslateCTM 上下文平移变换 CGContextScaleCTM CGContextRotateCTM
图片处理相关api
CGImageRef
CGImageGetWidth(imageRef) CGImageGetBitsPerComponent(imageRef) CGImageRelease(decompressedImageRef);
CGBitmapInfo
typedef CF_OPTIONS(uint32_t, CGBitmapInfo) { kCGBitmapAlphaInfoMask = 0x1F, kCGBitmapFloatComponents = (1 « 8),
kCGBitmapByteOrderMask = 0x7000, kCGBitmapByteOrderDefault = (0 « 12), kCGBitmapByteOrder16Little = (1 « 12), kCGBitmapByteOrder32Little = (2 « 12), kCGBitmapByteOrder16Big = (3 « 12), kCGBitmapByteOrder32Big = (4 « 12) } CF_ENUM_AVAILABLE(10_4, 2_0);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef)
创建和释放位图上下文
CGBitmapContextCreate() CGContextRelease(context);
CGContextDrawImage() 将图像绘制到指定的context CGBitmapContextCreateImage(context) 使用context创建image void * CGBitmapContextGetData (CGContextRef c);
CGImageMaskCreate() 创建一个bitmap image mask CGImageCreateWithMask(image,mask) 合成image 和 image mask