转载自:http://m.2cto.com/kf/201612/572489.html
柱状图
1.构建数据, NSArray *data = @[@300, @150.65, @55.3, @507.7, @95.8, @700, @650.65];
2.根据数据的个数绘制柱状图。
3.计算每个柱子的 x,y,w,h 即可
#pragma mark - 绘制柱形图 - (void)drawRect:(CGRect)rect { // 1.数据 NSArray *data = @[@300, @150.65, @55.3, @507.7, @95.8, @700, @650.65]; // 2.获取图形上下文 CGContextRef cxtRef = UIGraphicsGetCurrentContext(); // 计算宽度 CGFloat width = rect.size.width / (data.count * 2 - 1); // 3.遍历集合创建路径对象 for (int i = 0; i < data.count; i++) { // 计算x, y, 高度 CGFloat x = i * (width * 2); CGFloat height = [data[i] intValue] / 1000.0 * rect.size.height; NSLog(@"%f", height); CGFloat y = rect.size.height - height; // 创建路径对象 UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, width, height)]; [[UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1.0] set]; // 将路径对象添加到图形上下文中 CGContextAddPath(cxtRef, path.CGPath); // 渲染 CGContextDrawPath(cxtRef, kCGPathFillStroke); } }
Quartz2D内存管理
1> 通过product->Analyze来进行内存分析
2> 使用注意:对于C语言的框架,通过使用”create” “copy” “retain”函数创建的对象,使用完毕后都要进行释放
3> 解决办法
CGPathRelease();// 释放路径对象
CFRelease(); // 可以释放任何对象
-使用Path 对象时的内存管理问题:
1> 凡是遇到 retain 、 copy 、 create 出的对象, 都需要进行 release
2> 但是CGPathCreateMutable()不是 OC方法, 所以不是调用 某个对象的 release方法
3> CGXxxxxCreate 对应的就有 CGXxxxxRelease。
4> 通过 CFRelease(任何类型);可以释放任何类型。
图片和文字绘制
- (void)drawRect:(CGRect)rect { [self imageDemo]; [self strDemo]; } #pragma mark - 图片的绘制 - (void)imageDemo { // 1.获取图片 UIImage *image = [UIImage imageNamed:@"me"]; // 2.3种方式绘制 // - 从某个点开始绘制图片 // [image drawAtPoint:CGPointZero]; // - 在某个区域绘制图片 [image drawInRect:CGRectMake(100, 100, 200, 300)]; // - 以平铺的方式绘制图片 // [image drawAsPatternInRect:rect]; } #pragma mark - 绘制文字 - (void)strDemo { // 1.文字 NSString *str = @"理想很丰满,现实很滑感"; // 2.绘制 NSDictionary *dict = @{ NSFontAttributeName : [UIFont systemFontOfSize:20], NSForegroundColorAttributeName : [UIColor redColor] }; // MARK: - 1.从某个点绘制文字! // [str drawAtPoint:CGPointMake(50, 50) withAttributes:dict]; // MARK: - 2.在某个区域绘制文字,并且会自动换行,如果超出范围,显示不全! [str drawInRect:CGRectMake(100, 350, 100, 50) withAttributes:dict]; }
自定义UIImageView
剪裁原型图片设置个人中心个性头像
- (void)drawRect:(CGRect)rect { // 1.获取图形上下文 CGContextRef cxtRef = UIGraphicsGetCurrentContext(); // MARK: - 2.在添加被裁剪路径之前,有别的内容被渲染了,之前渲染的内容是否能够显示? UIBezierPath *round2 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 100, 100)]; // 添加别的路径 CGContextAddPath(cxtRef, round2.CGPath); // 设置线宽 CGContextSetLineWidth(cxtRef, 10); // 设置线条颜色 [[UIColor whiteColor] setStroke]; // 渲染 CGContextDrawPath(cxtRef, kCGPathStroke); // 2.创建一个要裁剪的图形的路径【圆形】 CGPoint center = CGPointMake(150, 150); CGFloat radius = 50; CGFloat startA = 0; CGFloat endA = M_PI * 2; BOOL clockwise = YES; UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:clockwise]; // 3.将圆形的路径添加到图形上下文中[不能渲染] CGContextAddPath(cxtRef, path.CGPath); // MARK: - 1.路径被渲染了,是否还能够裁剪? // 裁剪就达不到效果了! // CGContextDrawPath(cxtRef, kCGPathStroke); // 4.裁剪! CGContextClip(cxtRef); // 5.把图片画上去 [[UIImage imageNamed:@"me"] drawAtPoint:CGPointMake(100, 100)]; }
剪裁图片赋值到imageview上,并保存到沙盒或者相册
#pragma mark - 点击裁剪按钮调用的! - (IBAction)clipBtnClick:(UIButton *)sender { // 0.图片 UIImage *image = [UIImage imageNamed:@"me"]; // 1.需要开启图片的图形上下文 /** * size 开启的图形上下文的大小 * opaque 不透明! YES[不透明,四个角是黑色的!],NO[透明] -> NO * scale 屏幕的缩放因子! 0.0-> 直接匹配当前设备屏幕的缩放因子! */ UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0); // 2.获取当前的图形上下文!【图片的图形上下文】 CGContextRef cxtRef = UIGraphicsGetCurrentContext(); // 3.创建一个圆形的路径 // 椭圆 -> 圆形! UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; // 4.将圆形路径添加到图形上下文 CGContextAddPath(cxtRef, path.CGPath); // 5.裁剪 CGContextClip(cxtRef); // 6.把图片绘制出来 [image drawAtPoint:CGPointZero]; // 7.从当前的图形上下文中获取图片 UIImage *clipImg = UIGraphicsGetImageFromCurrentImageContext(); // 8.把图片的图形上下文进行关闭 UIGraphicsEndImageContext(); // MARK: - 展示图片 UIImageView *imgView = [[UIImageView alloc] initWithImage:clipImg]; imgView.center = CGPointMake(100, 200); [self.view addSubview:imgView]; // MARK: - 1.保存图片到沙盒! // 1.沙盒路径 NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"xxx.png"]; // 2.把图片存进去 // 2.1 需要将图片转为NSData类型数据 NSData *data = UIImagePNGRepresentation(clipImg); // 2.2 将二进制数据写入文件,就可以了! [data writeToFile:filePath atomically:YES]; // MARK: - 1.保存图片到相册! /** image : 要保存的图片 completionTarget : 存储结束后,监听的对象! completionSelector: 存储结束后,监听的对象需要执行的方法! contextInfo: 上下文信息,可以写字符串,或中nil,最大的作用:可以帮助区分是哪个图片被存进去了! // 第一次进行图片存储时,会提醒用户,应用要访问相册,需要用户的许可,才可以存储! // 以后就不会再进行提示了!可以通过设置里面进行权限修改! */ // UIImageWriteToSavedPhotosAlbum(clipImg, nil, nil, nil); UIImageWriteToSavedPhotosAlbum(clipImg, self, @selector(image:didFinishSavingWithError:contextInfo:), @"touxiang"); } /** * @param image 存储的图片 * @param error 错误信息,如果存储出错,会返回对应的错误信息! * @param contextInfo 上下文信息,上传什么,这里就是什么 */ - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { if (error) { NSLog(@"出错了 %@", error); return; } NSLog(@"存储成功 %@", contextInfo); }
文字水印和图片水印绘制
1、添加文字水印
1> 创建位图上下文
2> 把图片画上去
3> 把文字画上去
4> 从上下文中取出图片
2、添加图片水印
1> 创建位图上下文
2> 把图片画上去
3> 加载 logo 图片(水印图片),把水印图片也画上去
4> 从上下文中取出图片
#pragma mark - 文字水印 / 图片水印绘制 - (void)demo2 { // 1.开启图片的图形上下文 UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 400), NO, 0.0); // 2.获取当前的图形上下文 // CGContextRef cxtRef = UIGraphicsGetCurrentContext(); // 3.将littleDog绘制上去! [[UIImage imageNamed:@"littledog"] drawInRect:CGRectMake(0, 0, 300, 400)]; // 4.将文字绘制上去! [@"旺旺旺旺" drawAtPoint:CGPointMake(100, 100) withAttributes:@{ NSForegroundColorAttributeName : [UIColor magentaColor], NSFontAttributeName: [UIFont systemFontOfSize:30] }]; // 4.绘制图片水印 [[UIImage imageNamed:@"logo"] drawAtPoint:CGPointMake(100, 200)]; // 5.从当前上下文中取出图片 UIImage *textImg = UIGraphicsGetImageFromCurrentImageContext(); // 6.关闭图形上下文 UIGraphicsEndImageContext(); // 7.展示图片 UIImageView *imgView = [[UIImageView alloc] initWithImage:textImg]; imgView.center = self.view.center; [self.view addSubview:imgView]; }
屏幕截屏
核心代码
- (void)renderInContext:(CGContextRef)ctx;
调用某个view的layer的renderInContext:方法即可
截图基本思路:
1、获取控件的 layer 对象
2、调用 layer 对象的 renderInContext:方法渲染到上下文中
**注意:UISegmentedControl 渲染时有问题
#pragma mark - 截图按钮被点击 - (IBAction)btnClick:(id)sender { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 1.开启图片的图形上下文 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0); // 2.获取图形上下文 CGContextRef cxtRef = UIGraphicsGetCurrentContext(); // 3.将视图的layer【层】渲染[render]到上下文中 [self.view.layer renderInContext:cxtRef]; // 4.获取图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 5.关闭上下文 UIGraphicsEndImageContext(); // 6.保存到相册 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); });
网友评论