#pragma mark - 使用默认的context绘制直线
-(void)drawLine{
// 1. 取得上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 2. 起始点
CGContextMoveToPoint(context, 50, 50);
// 1) 起始点到第一个点
CGContextAddLineToPoint(context, 200, 200);
// 2) 第一个点到第二个点 如果不封闭图形就是两条线
CGContextAddLineToPoint(context, 20, 200);
// 3) 封闭图形后就是三角形
CGContextClosePath(context);
// 3. 设置属性
// 设置边线
[[UIColor redColor] setStroke];
// 设置填充
[[UIColor blueColor] setFill];
// 设置边线和填充
// [[UIColor greenColor] set];
// 4. 绘制路径 虽然没有直接定义路径,但是第2步操作,就是为上下文指定路径
CGContextDrawPath(context, kCGPathFillStroke);
}
#pragma mark - 使用路径绘制直线
-(void)drawLine2{
// 提示,使用Ref声明的对象,不需要用*
// 1. 获取上下文-UIView对应的上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 2. 创建可变的路径并设置路径
CGMutablePathRef path = CGPathCreateMutable();
// 划线->
// 1) 设置起始点
CGPathMoveToPoint(path, NULL, 50, 50);
// 2) 设置目标点
CGPathAddLineToPoint(path, NULL, 200, 200);
CGPathAddLineToPoint(path, NULL, 50, 200);
// 3) 封闭路径
CGPathCloseSubpath(path);
// 3. 将路径添加到上下文
CGContextAddPath(context, path);
// 4. 设置上下文属性
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 1.0);
// 设置线条宽度
CGContextSetLineWidth(context, 5.0);
// 设置线条的顶点样式
CGContextSetLineCap(context, kCGLineCapRound);
// 设置线条的连接点样式
CGContextSetLineJoin(context, kCGLineJoinRound);
// 设置线条的虚线样式
CGFloat lengths[2] = {20.0,10.0};
CGContextSetLineDash(context, 0.0, lengths, 2);
// 5. 绘制路径
CGContextDrawPath(context, kCGPathFillStroke);
// 6. 释放路径
CGPathRelease(path);
}
#pragma mark - 绘制矩形
-(void)drawShapeRect{
CGRect rect = CGRectMake(50, 50, 200, 200);
[[UIColor redColor] set];
// 绘制实心矩形
UIRectFill(rect);
// 绘制空心矩形
UIRectFrame(CGRectMake(50, 300, 100, 100));
}
#pragma mark - 绘制圆形
-(void)drawShapeCycle{
// 1. 取出上下文
CGContextRef context = UIGraphicsGetCurrentContext();
UIRectFrame(CGRectMake(50, 50, 200, 100));
// 2. 设置路径
CGContextAddEllipseInRect(context, CGRectMake(50, 50, 200, 100));
// 3. 绘制圆形路径
CGContextDrawPath(context, kCGPathFillStroke);
}
#pragma mark - 绘制圆弧
-(void)drawArc{
// 1. 取得上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 2. 设置路径
CGContextAddArc(context, 160, 230, 100, -M_PI_4, M_PI_4, 0);
// 3. 绘制路径
CGContextDrawPath(context, kCGPathStroke);
}
#pragma mark - 绘制文字 中文竖排
-(void)drawText{
NSString * str = @"Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world ";
NSString * str1 = @"般若波罗蜜多心经";
// 指定点绘制字符串
// [str drawAtPoint:CGPointMake(50, 50) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];
// 如果在UILabel中,可以将numbersOfLine设置为0,并且指定足够的高度即可
[[UIColor lightGrayColor] set];
UIRectFill(CGRectMake(8, 50, 150, 360));
// 在指定区域绘制字符串 横向
[str drawInRect:CGRectMake(8, 50, 150, 360) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];
[[UIColor lightGrayColor] set];
UIRectFill(CGRectMake(162, 50, 30, 360));
// 中文竖排 就是让rect的宽度窄一些 这样字符串就垂直了
[str1 drawInRect:CGRectMake(162, 50, 30, 360) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor brownColor]}];
}
#pragma mark - 绘制图像
-(void)drawImage{
UIImage * img = [UIImage imageNamed:@"头像1.png"];
// 提示:绘制之后,就无法改变位置,也没有办法监听手势识别
// 在指定点绘制图像 Point top-left corner of the image
[img drawAtPoint:CGPointMake(50, 50)];
// 会在指定的矩形中拉伸绘制
[img drawInRect:CGRectMake(0, 0, 320, 460)];
// 在指定矩形区域中平铺图片
[img drawAsPatternInRect:CGRectMake(0, 0, 320, 460)];
}
#pragma mark - 绘制五角星
分析 我们绘图肯定是要要直线 那么就要计算 画一条直线所走过的圆心角 给五角星的角度编号 0 ,1 ,2, 3, 4 第一条直线应才是0 ->2 那么它走过的角度上 2/5 *360 = 144度(从0->1 为一个内角 五个内角加起来值为360) 同理第二条第三条第四条也是的 ; 假如我们把0刚好放在y坐标正轴上(坐标是 0, r) 那么我们可以算出2这个点的 x y 坐标 分析的知 x = r * cos((2 * M_PI / 5.0) * 2.0 - M_PI_2) y = r* sin((2 * M_PI / 5.0) * 2.0 - M_PI_2) M_PI表示圆周率 不是表示360 角度转换成弧度的公式 : (角度 * 2π)/ 360 所以144度 144 * M_PI/180=(4/5)* M_PI
@interface DrawFivePointStar() {
// 是否已经计算过五角星顶点
BOOL _hasPoint;
// 记录五角星的五个顶点 数组
CGPoint points[5];
}
@end
@implementation DrawFivePointStar
#pragma mark - 记录五角星的五个顶点
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect { // 这里其实只调用了一次
if (!_hasPoint) { // 没有计算过角度 第一次 初始的时候
[self loadPoints];
_hasPoint = YES;
}
static int times = 0 ;
NSLog(@"%d",++times);
CGContextRef context = UIGraphicsGetCurrentContext();
[self drawRandomStarWithContext:context count:16];
}
#pragma mark - 通过第一个点 计算出五角星的五个顶点坐标
-(void)loadPoints{
// 半径
CGFloat r = 100 ;
// 第一个点的坐标是 中心点(0,0) 第一个点坐标为( 0, 0-r )
points[0] = CGPointMake(0, -r);
// 每画一条直线转过的角度 每次旋转 (2 * M_PI / 5.0) * 2.0 = 144 度 M_PI表示圆周率 不是表示360
CGFloat angle = (4.0/5.0) * M_PI ;
// 计算出画四条线每条线的坐标是
for (int i = 1; i<5; i++) {
// 计算出下一个点的坐标 相对的(0,0)计算的
CGFloat x = r * cosf(i*angle - M_PI_2);
CGFloat y = r * sinf(i*angle - M_PI_2) ;
points[i]=CGPointMake(x, y);
}
}
#pragma mark - 对画的五角星进行位置 角度 大小的随机设置
-(void)drawRandomStarWithContext:(CGContextRef )context count:(NSInteger) count{
for (NSInteger i = 0 ; i<count; i++) {
// 保存上下文 最初的坐标系
CGContextSaveGState(context);
// 下列操作会改变当前context的坐标系
// 平移上下文
CGFloat x = arc4random()%320;
CGFloat y = arc4random()%480;
CGContextTranslateCTM(context, x, y);
// 旋转上下文
CGFloat angle = (arc4random()%180 * M_PI/180.0);
CGContextRotateCTM(context, angle);
// 缩放上下文
CGFloat scale = arc4random_uniform(5)/10.0 + 0.5 ;
CGContextScaleCTM(context, scale, scale);
// 绘制五角星
[self drawStarWithContext:context];
// 恢复之前的上下文 最初的坐标系
CGContextRestoreGState(context);
}
}
#pragma mark - 对画的五角星的颜色进行随机赋值
-(UIColor *)randomColor{
CGFloat r = arc4random_uniform(255)/255.0;
CGFloat g = arc4random_uniform(255)/255.0;
CGFloat b = arc4random_uniform(255)/255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1.0];
}
#pragma mark - 绘制五角星
-(void)drawStarWithContext:(CGContextRef ) context{
[[self randomColor] set];
// 设置起始点
CGContextMoveToPoint(context, points[0].x, points[0].y);
// 设置路径,计算其他四个点的坐标 技巧, 一个一个计算调试 否则画太多不好调试
for (int i = 1; i<5; i++) {
CGContextAddLineToPoint(context, points[i].x, points[i].y);
}
// 关闭路径
CGContextClosePath(context);
// 绘制路径
CGContextDrawPath(context, kCGPathFillStroke);
}
#pragma mark - 绘制线性渐变 裁剪
-(void)drawLinearGradient{
// 在计算机中直接选RGB即可 其他的颜色空间暂时不做考虑
// 1. 创建色彩空间上下文 注意这里用的 create 所以后面得要release
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// 2. 创建渐变的色彩组成
CGFloat components[12] = {
1.0,0.0,0.0,1.0,
0.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0
};
// CGFloat locations[3] = {0.0,0.2,1.0};
CGFloat locations[3] = {0.2,0.0,1.0};
// 3. 创建渐变 注意这里用的 create 所以后面得要release
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 3);
// 渐变的区域裁剪
CGRect rects[5] = {
CGRectMake(0, 0, 100, 100),
CGRectMake(200, 0, 100, 100),
CGRectMake(100, 100, 100, 100),
CGRectMake(200, 200, 100, 100),
CGRectMake(0, 200, 100, 100)
};
// 裁剪 后面画图能够显示的返回就是裁剪出来的范围 在图片裁剪上这个应用的很多 很重要 !!!
CGContextClipToRects(UIGraphicsGetCurrentContext(), rects, 5);
// 4. 通过上下文 绘制线性渐变
CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), gradient, CGPointMake(0, 0), CGPointMake(320, 480), kCGGradientDrawsAfterEndLocation);
// 5. 释放对像
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradient);
}
#pragma mark - 绘制径向渐变
-(void)drawRadialGradient{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[12]={
1.0,0.0,0.0,1.0,
0.0,1.0,1.0,1.0,
0.0,0.0,1.0,1.0
};
CGFloat locations[3] = {0.0,0.6,1.0};
// 这里也可以裁剪区域 本处没有裁剪
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 3);
// 绘制渐变
CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(), gradient, CGPointMake(160, 240), 160, CGPointMake(160, 240), 50, kCGGradientDrawsAfterEndLocation);
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradient);
}
注意:以上方法都是在一个继承自UIView的子类中操作的 也就是说 在UIViewController里面这样 画图是画不出任何东西的(线,字符串,图片都画不出来) 但是其实他的操作还是进行了
#pragma mark - 在ViewController中 绘制图片水印
@interface ImageWaterMarkVC (){
UIImageView * imgV;
}
@end
@implementation ImageWaterMarkVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UIButton * btn =[[UIButton alloc] initWithFrame:CGRectMake(100, 0, 150, 50)];
btn.backgroundColor=[UIColor lightGrayColor];
[btn setTitle:@"给图片加水印" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
UIImage * img = [UIImage imageNamed:@"NatGeo01.png"];
imgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 80, 320, 200)];
imgV.image = img;
[self.view addSubview:imgV];
}
-(void)btnClick:(UIButton*)sender{
// UIImage * newImage = [self waterMarkImage:imgV.image WithTitle:@"FromWK"];
UIImage * newImage = [self waterMarkImageView:imgV withTitle:@"FromWK"];
NSLogSize(newImage.size);
imgV.image = newImage;
}
// 使用这个方法涉及到 像素-->点-->像素 返回的像素和原来一样 那么画上的水印在@2x上会缩小一倍(1点2像素) 因此不如直接都用点来进行操作不涉及像素的问题 也就是直接用imageView自身的点数来进行操作
-(UIImage*)waterMarkImage:(UIImage*)img WithTitle:(NSString*)title{
UIImage * newImage = nil;
// img.size 是直接把像素点按照1:1还算成点的 后面的操作都是针对点
CGSize imageSize = img.size;
// 1. 建立图像的上下文,需要指定新生成的图像大小
UIGraphicsBeginImageContext(imageSize);
// 2. 选择要显示图片的类容大小 drawInRect: 最终的图片的大小是此Rect的大小 但是有效(有image图像)的部分 是根据图片本身的大小以及图片相对于此Rect的 x , y 坐标 如下面的 (0,0)
[img drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
// 3. 画上要添加的水印 注意因为此处用到的是点操作
[title drawInRect:CGRectMake(20, imageSize.height-30, imageSize.width-40, 30) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor redColor]}];
// 4. 取得经过这样画图后的新图片
newImage = UIGraphicsGetImageFromCurrentImageContext();
// 5. 关闭图像上下文 释放内存
UIGraphicsEndImageContext();
// 返回的 newImage 又把点操作1:1的替换成了像素 这样就导致了一个问题 就是你画上去的水印如果显示在@2x屏幕上会缩小一倍 如果是@3x为缩小三倍
return newImage;
}
// 直接用点数进行操作
-(UIImage*)waterMarkImageView:(UIImageView*)imgView withTitle:(NSString *)title{
UIImage * newImage = nil;
// 直接用需要显示在的imageView的点来进行操作
CGSize imageSize = imgView.frame.size;
UIGraphicsBeginImageContext(imageSize);
[imgView.image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
[title drawInRect:CGRectMake(20, imageSize.height-30, imageSize.width-40, 30) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17],NSForegroundColorAttributeName:[UIColor redColor]}];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
#pragma mark 模仿备忘录中的背景效果 背景平铺(一行一行的平铺)
@implementation MemoBackgroundVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[self createMemoBackgroundImage]]];
}
-(UIImage*)createMemoBackgroundImage{
UIImage * cellImage = nil;
// 1. 图像上下文
UIGraphicsBeginImageContext(CGSizeMake(320, 46));
// 2. 画图
// 1) 画背景的矩形
[[UIColor yellowColor] set];
UIRectFill(CGRectMake(0, 0, 320, 46));
// 2) 画底部的灰线
[[UIColor lightGrayColor] set];
UIRectFill(CGRectMake(0, 44.5, 320, 1.5));
// 3. 取得图片
cellImage = UIGraphicsGetImageFromCurrentImageContext();
// 4. 关闭上下文 释放内存
UIGraphicsEndImageContext();
// 5. 返回图像
return cellImage;
}
@end
#pragma mark 画PDF格式文件
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self createPDFFile];
}
-(void)createPDFFile{
// 1. 取得存储路径
NSString * path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"123.PDF"];
NSLog(@"%@",path);
// 2. 创建PDF上下文
UIGraphicsBeginPDFContextToFile(path, CGRectZero, NULL);
// 3. 创建PDF内容
for (int i =0 ; i < 6; i++) {
// 1) 创建PDF页面 每页的装载数量是有限的 此图片的大小为 640 × 400像素 所以在默认的页面中只能装两张图片
// 每添加两张图片后 需要重新建立一个页面
if (i%2) {
UIGraphicsBeginPDFPage();
}
// 2) 将Image添加到PDF文件
NSString * imageName = [NSString stringWithFormat:@"NatGeo%02d",i+1];
UIImage * img = [UIImage imageNamed:imageName];
[img drawInRect:CGRectMake(0, (i%2)*396, 612, 396)];
}
// 4. 关闭PDF上下文 释放内存
UIGraphicsEndPDFContext();
}
#pragma mark 屏幕截图
- + (instancetype)captureWithView:(UIView *)view
- {
- // 1.开启上下文
- UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0);
- // 2.将控制器view的layer渲染到上下文
- [view.layer renderInContext:UIGraphicsGetCurrentContext()];
- // 3.取出图片
- UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
- // 4.结束上下文
- UIGraphicsEndImageContext();
- return newImage;
- }
如果一个继承自UIView的MyView 显示在了ViewController中 MyView包含了一个 画上去的字符串 需要在ViewController中来改变MyView显示(这个画上去的字符串)的内容和字体大小 那么
1. MyView需要有连个属性 一个是字符串 另一个是字符串大小
2. 需要重写MyView的这两个属性的set方法 在方法里加上 [self setNeedsDisplay]; 这个方法的调用 来实时的刷新MyView的显示
CGBitmapContextCreate函数参数详解
函数原型:
CGContextRef CGBitmapContextCreate (
void *data, 指向要渲染的绘制内存的地址
size_t width, bitmap的宽度,单位为像素
size_t height, bitmap的高度,单位为像素
size_t bitsPerComponent, 内存中像素的每个组件的位数.例如,对于32位像素格式和RGB 颜色空间,你应该将这个值设为8
size_t bytesPerRow, bitmap的每一行在内存所占的字节数
CGColorSpaceRef colorspace, bitmap上下文使用的颜色空间
CGBitmapInfo bitmapInfo 指定bitmap是否包含alpha通道,像素中alpha通道的相对位置,像素组件是整形还是浮点型等信息的字符串。
)
描述:创建一个位图的上下文 此上下文向一个位图绘制图像 该位图的宽高是以像素为单位的
每个像素的组件个数是通过space来指定的 当然space可能也指定了一个目标颜色的配置文件
每个像素的每个组件的位数是通过 bitsPerComponent 来指定的
每个像素的字节数 = (每个像素的每个组件的位数 * 每个像素的组件的个数 +7 )/ 8 (一个字节一般是八位)
位图的每一行由 bytesPerRow个字节组成 且 bytesPerRow >= width * 每个像素的字节数 此外 bytesPerRow 必须是每个 像素字节数的整数倍
data 如果不为空 那么他指向的内存块至少是 bytesPerRow * 高度个字节
如果为空 上下文的字节数空间将会自动被创建和销毁 并且 bytesPerRow 应该传递参数0来让系统自动计算内存空间
bitmapInfo 位图信息 指定是否本位图应该包含一个透明图的通道以及他是如和 生成的 还有就是组件是浮点型还是整型
位图: 是由像素组成要有足够多的不同色彩的像素,就可以制作出色彩丰富的图象,逼真地表现自然界的景象,缩放和旋转容易失真,同时文件容
量较大, 位图颜色的编码有 RGB(屏幕显示) CMYK等 其图像属性有 索引颜色/颜色表 Alpha通道 色彩深度
矢量图像:是由数学向量组成文件容量较小,在进行放大、缩小或旋转等操作时图象不会失真,不易制作色彩变化太多的图象)
当你调用这个函数的时候,Quartz创建一个位图绘制环境,也就是位图上下文。当你向上下文中绘制信息时,Quartz把你要绘制的信息作为位图数据绘制到指定的内存块。一个新的位图上下文的像素格式由三个参数决定:每个组件的位数,颜色空间,alpha选项。alpha值决定了绘制像素的透明性
- 在 iOS7以前,是使用如下方法创建的:
- CG_EXTERN CGContextRef CGBitmapContextCreate(voidvoid *data, size_t width,
- size_t height, size_t bitsPerComponent, size_t bytesPerRow,
- CGColorSpaceRef space,CGImageAlphaInfo bitmapInfo)
注意最后一个参数类型是 CGImageAlphaInfo 枚举类型中的kCGImageAlphaPremultipliedLast值。其整型值为1
- typedef CF_ENUM(uint32_t, CGImageAlphaInfo)
- {
- kCGImageAlphaNone,
- kCGImageAlphaPremultipliedLast,
- kCGImageAlphaPremultipliedFirst,
- kCGImageAlphaLast,
- kCGImageAlphaFirst,
- kCGImageAlphaNoneSkipLast,
- kCGImageAlphaNoneSkipFirst,
- kCGImageAlphaOnly
- };
- 但是在iOS7版本中,这个最后的参会类型发生了变化。看一下定义:
- CGContextRef CGBitmapContextCreate(voidvoid *data, size_t width,
- size_t height, size_t bitsPerComponent, size_t bytesPerRow,
- CGColorSpaceRef space, CGBitmapInfo bitmapInfo)
- 很明显最后一个参数由CGImageAlphaInfo 变化为 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);
- 从头到尾没有发现值为1的枚举量值。故在使用的时候会出现如下警告:
Implicit conversion from enumeration type 'enum CGImageAlphaInfo' to different enumeration type 'CGBitmapInfo' (aka 'enum CGBitmapInfo')
- 意思很明显不过,类型不匹配非法。
- 以下给出解决方法:
第一种方法,定义宏:
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
- #define kCGImageAlphaPremultipliedLast (kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast)
- #else
- #define kCGImageAlphaPremultipliedLast kCGImageAlphaPremultipliedLast
- #endif
这样就会直接映射出一个值为1的宏,原有方法不用改变
- 第二种方法:原理和第一个一样,目的 还是为了生产出一个为1的值,直接修改代码。
- #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
- int bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
- #else
- int bitmapInfo = kCGImageAlphaPremultipliedLast;
- #endif
- CGContextRef context = CGBitmapContextCreate(nil, CGContexWith*2, 290.0*2, 8, 4*CGContexWith*2, colorSpace, bitmapInfo);
- 其实所有的做法,不外乎为了使这里的值为1,类型匹配。你也直接可以传1,不用麻烦的各种写代码。也可以直接进行类型强制转换,这个你随便。只是每个人的习惯不一样,故,如何解决,自己参考决定 。