转载自:http://www.tuicool.com/articles/7jqANnm
- 昨天写了一篇文章 quartz2D 的从零到一学习使用(附赠源码) ,是关于quartz2D比较基础用法的总结,今天讲讲进阶的知识
1.将方形图片绘制成圆形图片
2.给图片加水印
3.将图片裁剪成圆形
4.将图片裁剪成带有边框的圆形
5.屏幕截屏
一.将方形图片绘制成圆形图片
在实际开发过程中,我们常常使用到将图片的变成圆形,我们想讲讲如何用quartz2D 绘制 一个圆形的图片
原始图片
通过以下代码绘制成圆形的图片
- (void)drawRect:(CGRect)rect { //1.获取图形上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //2.画个圆 CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 70, 70)); //3.剪切 CGContextClip(ctx); //4.将图片绘制上去 UIImage *image = [UIImage imageNamed:@"5.jpg"]; [image drawAtPoint:CGPointMake(0, 0)]; //5.渲染 CGContextFillPath(ctx); }
绘制的圆形图片
1.使用图形上下文,一定是要先获取
2.我们打算绘制一个圆形的,所以,先绘制一个圆形,在去使用 CGContextClip
剪切,以后绘制的任何东西,不论在任何位置,只有处在圆心的位置才会显示。
使用三角形裁剪图片
随意画一个三角形,然后绘制图片
- (void)drawRect:(CGRect)rect { //1.获取图形上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //2.画个三角形 CGContextMoveToPoint(ctx, 0, 10); CGContextAddLineToPoint(ctx, 250, 67); CGContextAddLineToPoint(ctx, 256, 190); CGContextClosePath(ctx); //3.剪切 CGContextClip(ctx); //4.将图片绘制上去 UIImage *image = [UIImage imageNamed:@"5.jpg"]; [image drawAtPoint:CGPointMake(0, 0)]; //绘制一个正方形 [[UIColor redColor] set]; // CGContextAddRect(ctx, CGRectMake(10, 10, 203, 240)); //5.渲染 CGContextFillPath(ctx); }
- 想在里面绘制一个红色的矩形,于是打开注释代码
CGContextAddRect(ctx, CGRectMake(10, 10, 203, 240))
,得到了这个图片
在绘制一个矩形
1.也就是说,只要你调用 CGContextClip
裁剪方法,那么将来所有的绘制,都只能在裁剪的范围只能绘制
2.如果我们想不受裁剪的影响,想在三角形旁边绘制一个rect,就要用到图形上下文栈的知识了
出战在redColor之后
出战在redColor之前
- (void)drawRect:(CGRect)rect { //1.获取图形上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //1.1保存空白的上下文 CGContextSaveGState(ctx); //2.画个三角形 CGContextMoveToPoint(ctx, 0, 10); CGContextAddLineToPoint(ctx, 250, 67); CGContextAddLineToPoint(ctx, 256, 190); CGContextClosePath(ctx); //3.剪切 CGContextClip(ctx); //4.将图片绘制上去 UIImage *image = [UIImage imageNamed:@"5.jpg"]; [image drawAtPoint:CGPointMake(0, 0)]; //绘制一个正方形 //还原上下文 CGContextRestoreGState(ctx); [[UIColor redColor] set]; CGContextAddRect(ctx, CGRectMake(10, 10, 20, 230)); //5.渲染 CGContextFillPath(ctx); }
总结:
1.想去剪切图片,而且不形象别的绘制图片,就是用上下文
2.使用 绘制图片 ,我们只是在上下文中显示了,但是要知道 我们没有获得一张三角形或者圆形的照片!
二.给图片加水印
1.过去我们做demo使用的是图层上下文,实际上就是将东西绘制到CALayer上,用UIVIew来显示,但是获取不到具体的图片。
2.位图上下文,我们将东西绘制,然后获取一张 图片,不再是一个UIVIew了
2.5 绘制到东西到不同上下文,获取的结果是不一样的
3.使用图层上下文,绘制的时候通过 UIGraphicsGetCurrentContext
在 drawRect
方法中获取已经生成好的图形上下文。
4.使用 位图上下文 可以在viewdidLoad中直接写,使用begin,end方法去开启和关闭位图上下文
想将两张图片合成一下,制作出一个水印效果的UIImage图片,保存到本地
水印logo
背景图片
- (void)viewDidLoad {
[super viewDidLoad];
//0.获取旧的图片
UIImage *oldImage = [UIImage imageNamed:@"5.jpg"];
//1.开启位图上下文(这句话的意思就是生产了一个这么大的图片!)
// UIGraphicsBeginImageContext(oldImage.size);
/**
* 有两种开启位图上下文的方法,推荐第二种
* size 生成图片的大小,和oldIamge一样大
* opaque 不透明,YES是不透明,NO是透明
* scale 拉伸比例,推荐不拉伸 0.0
*/
UIGraphicsBeginImageContextWithOptions(oldImage.size, NO, 0.0);
//2.绘制背景图片
[oldImage drawAtPoint:CGPointZero];
//3.绘制logo图片
UIImage *logoImg = [UIImage imageNamed:@"fgg.png"];
CGFloat margin = 10;
CGFloat logoX = oldImage.size.width - margin - logoImg.size.width;
CGFloat lognY = oldImage.size.height - margin - logoImg.size.height;
//绘制的位置
[logoImg drawAtPoint:CGPointMake(logoX,lognY)];
//4.获得新的照片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.关闭位图上下文
UIGraphicsEndImageContext();
//6.测试,我们将图片放到IamgeView上看看对不对
self.bgImageView.image = newImage;
}
合成之后的图片
- 开启位图上下文
UIGraphicsBeginImageContextWithOptions
2.调用 UIGraphicsBeginImageContextWithOptions
方法就是创建了一个图片,如果是水印,就是bgView的尺寸,也可以自定义size
3.绘制logo的时候,可以设置一个比例,或者具体的位置,这个看实际开发的要求
4.使用 UIGraphicsGetImageFromCurrentImageContext
方法获取 位图上下文制作的图片(如果是打水印,就是获取合成后的图片)
UIGraphicsEndImageContext
6. UIGraphicsGetImageFromCurrentImageContext
一定要在关闭之前执行,如果关闭了,就获取不到了
7.在实际的开发过程中,我们将 打印后的图片保存到沙河目录中 ,然后上传到自己的服务器中
//接着上边的代码写的 //7,将图片保存到本地沙河目录中 NSData *data = UIImagePNGRepresentation(newImage); //UIImageJPEGRepresentation 中第二个参数,代表压缩的质量,0-1之间,推荐1,但是这个方法出来的图片不如UIImagePNGRepresentation的好,所以推荐使用上边的 // NSData *data1 = UIImageJPEGRepresentation(newImage, 1); //8.保存到沙河目录中 NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"newIage.png"]; [data writeToFile:path atomically:YES]; //这样就可以保存图片到本地了,亲测可用,可以制作一个分类,方便管理使用
三.剪切方形图片成圆形
UIGraphicsBeginImageContextWithOptions中设置 不透明 属性为 YES,底部就是黑色的,建议设置成NO
设置成NO,周边都是透明的非常好
- (void)viewDidLoad { [super viewDidLoad]; //裁剪一个圆形的图片(最后会有两张图片,一张是原来方形的,一张是圆形的,过去的讲解的是,如何绘制到UIVIew,但是并没有生成新的图片) //获取过去的方形的图片 UIImage * oldIamge = [UIImage imageNamed:@"5.jpg"]; //1.开启图形上下文 //自定义一个高度也可以,不一定非要用照片的高度! CGFloat imgHeight = 100; UIGraphicsBeginImageContextWithOptions(CGSizeMake(imgHeight, imgHeight), NO, 0.0); //2.绘制一个圆形的图片,然后裁剪 CGContextRef ctx = UIGraphicsGetCurrentContext(); //绘制一个圆形 CGContextAddArc(ctx, imgHeight*0.5, imgHeight*0.5, imgHeight*0.5, 0, M_PI * 2, NO); //剪切上下文,只能在圈子里绘制东西 CGContextClip(ctx); //3.将image绘制到圆圈中 [oldIamge drawInRect:CGRectMake(0, 0, imgHeight, imgHeight)]; //4.获取新的照片 UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext(); //5.结束位图上下文 UIGraphicsEndImageContext(); //显示一下,保存到桌面中 self.bgImageView.image = newImg; //保存 NSData *data = UIImagePNGRepresentation(newImg); [data writeToFile:@"/Users/wangxin/Desktop/wangxin2.png" atomically:YES]; }
裁剪图片步骤
1.开启位图上下文,并设置大小,可以使照片的大小,也可以自己设置。我给了一个100dx
2. 获取图形上下文 ,绘制圆形供我们圈定绘图的范围
3.圈定好为绘图的范围,我们来 CGContextClip
裁剪
4.将图片绘制到指定的圆中
5.获取当前位图上下文所绘制的image
6.关闭上下文
四.将图片裁剪成带有边框的圆形
带有边框的图片
绘制带有边框的圆形图片如何制作?
100dx,边框为10dx
0.5+10,填充,绘制3.绘制一个小圆,用于将来切割,小圆的圆心和大圆相同,但是半径是原图高的一般,也就是100dx*0.5
4.圈定绘制范围
5.将原图绘制到小圆上(x = border,y=border)
6.获取新的图片
7.关闭上下文
8.使用图片即可
- (void)viewDidLoad { [super viewDidLoad]; //1.加载一张图片 UIImage * oldIamge = [UIImage imageNamed:@"5.jpg"]; //2.开启图像上下文 CGFloat border = 10; CGFloat imageW = oldIamge.size.width + 2*border; CGFloat imageH = oldIamge.size.height + 2*border; CGSize imageSize = CGSizeMake(imageW, imageH); UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0); //3.取得当前上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //4.绘制边框(大圆) [[UIColor redColor] set]; CGContextAddArc(ctx, imageW*0.5, imageH*0.5, imageW*0.5, 0, M_PI*2, NO); CGContextFillPath(ctx); //5.绘制小圆(oldimage那么大就行) [[UIColor blueColor] set]; CGContextAddArc(ctx, imageW*0.5, imageW*0.5, oldIamge.size.width*0.5, 0, M_PI*2, NO); //裁剪 CGContextClip(ctx); //6.将图片绘制到小圆上 [oldIamge drawInRect:CGRectMake(border, border, oldIamge.size.width, oldIamge.size.width)]; //7.获取当前上下文合成的图片 UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext(); //8.结束位图上下文 UIGraphicsEndImageContext(ctx); //9.显示和存储本地 self.bgImageView.image = newImage; NSData *data = UIImagePNGRepresentation(newImage); [data writeToFile:@"/Users/wangxin/Desktop/name1.jpg" atomically:YES]; }
五.剪切屏幕
用xib描述view是这样婶儿的
- (void)viewDidLoad { [super viewDidLoad]; //截屏 //1.开启上下文 UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0); //2.将控制器view的layer渲染到上下文 [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; //3.取出照片 UIImage *newIamge = UIGraphicsGetImageFromCurrentImageContext(); //4.保存到本地 NSData *data = UIImagePNGRepresentation(newIamge); [data writeToFile:@"/Users/wangxin/Desktop/name13.jpg" atomically:YES]; //5.关闭上下文 UIGraphicsEndImageContext(); }
截屏效果
1. self.view
就是截取的屏幕,我们可以随意的获取某个控件,通过 layer
截屏
2.所有的UI控件的本质,都是将东西绘制到CALayer,UIView就是一个容器,接受手势的,看到的东西都是 CALayer
截取的seg
写在后边
0.本文的所有功可以合并成分类,方便使用,高度自定义,非常好用
1.这些对图片的常用操作很使用,所以我们可以给UIImage写一个分类,将来拿来就用.代码在 进阶教程demo
2.推荐一个非常著名的第三方库 CorePlot
。绘制饼状图,柱状图,和K线图都非常方便。