iOS 绘图 (UIImage的一些操作)
UIGraphicsBeginImageContextWithOptions,本文主要在图片类型上下文中对图片进行操作,具体实现的功能:
-
- 1.生成图片
- 2.绘制图片到视图
- 3.添加水印
- 4.截取屏幕或者相应view
- 5.图片擦除
- 6.图片裁剪
具体的方法使用就在方法的介绍中解释吧,为了代码的复用,对上述方法进行了封装,放在UIImage的类别中,方便今后使用。
图片操作的基本步骤
1.开启图形上下文 2.绘制图片 - 使用drowInRect或者drawAtPoint绘制图片(区别在哪儿?你可以先想一想) drawInRect是以rect作为图片绘制的区域,图片是以填充的方式被绘制在当前区域图片的大小,rect的宽高比和原图片的宽高比不同时会造成图片的变形 drowAtPoint是以point作为图片绘制的起点,绘制的图片的大小依然是原图片的大小,不会使图片变形 - 将layer渲染在当前上下文 3.从当前上下文获取新的图片 4.关闭上下文
1.生成图片,这里我们生成特定颜色的图片
+ (UIImage *)createImageColor:(UIColor *)color size:(CGSize)size { //开启图形上下文 UIGraphicsBeginImageContextWithOptions(size, NO, 0); //绘制颜色区域 UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, size.width, size.height)]; [color setFill]; [path fill]; // CGContextRef ctx = UIGraphicsGetCurrentContext(); // CGContextSetFillColorWithColor(ctx, color.CGColor); // CGContextFillRect(ctx, CGRectMake(0, 0, size.width, size.height)); //从图形上下文获取图片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //关闭图形上下文 UIGraphicsEndImageContext(); return newImage; }
2.绘制图片,可以设置绘制的图片比例或者指定压缩后的图片的大小,可以当做压缩图片使用
+ (UIImage *)scaleImage:(UIImage *)image sclae:(CGFloat)scale { //确定压缩后的size CGFloat scaleWidth = image.size.width * scale; CGFloat scaleHeight = image.size.height * scale; CGSize scaleSize = CGSizeMake(scaleWidth, scaleHeight); //开启图形上下文 UIGraphicsBeginImageContext(scaleSize); //绘制图片 [image drawInRect:CGRectMake(0, 0, scaleWidth, scaleHeight)]; //从图形上下文获取图片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //关闭图形上下文 UIGraphicsEndImageContext(); return newImage; }
3.绘制水印
文字水印
可能你在添加文字水印之后,显示文字字体并不是你设置的字体大小,这是因为画布的size是图片的size,绘制后的图片被添加到ImageView上时可能被压缩或者放大,文字也就会发生变化。
+ (UIImage *)waterAtImage:(UIImage *)image text:(NSString *)text point:(CGPoint)point attributes:(NSDictionary *)attributes { //开启图形上下文 UIGraphicsBeginImageContextWithOptions(image.size, NO, 0); //绘制图片 [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; //添加文字 [text drawAtPoint:point withAttributes:attributes]; //获取图片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //关闭上下文 UIGraphicsEndImageContext(); return newImage; }
图片水印
+ (UIImage *)waterAtImage:(UIImage *)image waterImgae:(UIImage *)waterImage rect:(CGRect)rect { //开启图形上下文 UIGraphicsBeginImageContextWithOptions(image.size, NO, 0); //绘制原图片 [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.width)]; //绘制水印 [waterImage drawInRect:rect]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
4.截屏
1.创建图形上下文 2.将view的layer渲染到图形上下文 3.从图形上下文得到图片 4.关闭图像上下文
//当然如果你只是需要某个view的快照,在iOS7之后你可以使用[view snapshotViewAfterScreenUpdates:NO];来获得,比如实现长按拖拽cell的操作
+ (void)cutView:(UIView *)view success:(void(^)(UIImage *image))success { //开启图形上下文 UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0); //获取当前上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //渲染 [view.layer renderInContext:ctx]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); success(newImage); }
5.擦除
1.设置两张图片,上方为我们要擦除的图片,后方为需要展示的图片
2.设置擦除的区域的大小和位置
+ (UIImage *)wipeView:(UIView *)view point:(CGPoint)point size:(CGSize)size { //开启图形上下文 UIGraphicsBeginImageContext(view.bounds.size); //获取当前上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //渲染 [view.layer renderInContext:ctx]; //计算擦除的rect CGFloat clipX = point.x - size.width/2; CGFloat clipY = point.y - size.height/2; CGRect clipRect = CGRectMake(clipX, clipY, size.width, size.height); //将该区域设置为透明 CGContextClearRect(ctx, clipRect); //获取新的图片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
6.图片裁剪
矩形区域的裁剪,这里我们就利用drowAtPoint的特性去进行裁剪
1.假设一张图片的size是(600,600) 2.imageView的size是(300,300) 3.我们选择的裁剪区域是(10,10,150,150) 4.而我们为了能够保持原来图片的分辨率,在图片不拉伸的情况下在原图片上进行剪裁,所以实际我们在图片上的剪裁区域就是(20,20,300,300) 5.图片绘制在画布上的点就是(-20,-20),这样我们不需要进行裁剪就能获得我们想要得到的图片啦
+ (UIImage *)cutImage:(UIImage *)image imageViewSize:(CGSize)size clipRect:(CGRect)rect { //图片大小和实际显示大小的比例 CGFloat scale_width = image.size.width/size.width; CGFloat scale_height = image.size.height/size.height; //实际剪切区域 CGRect clipRect = CGRectMake(rect.origin.x * scale_width, rect.origin.y * scale_height, rect.size.width * scale_width, rect.size.height * scale_height); //开启图形上下文 UIGraphicsBeginImageContext(clipRect.size); //画图 [image drawAtPoint:CGPointMake(-clipRect.origin.x, -clipRect.origin.y)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
自定义点连线截图
1.将自定义点变换到在图片上的点 2.计算出自定义点所在的区域rect 3.开始图形上下文,rect.size 4.绘制path,机型剪裁 5.绘图drawAtPoint,x: - rect.origin.x y: - rect.origin.y 6.从图形上下文获取图片 7.关闭图形上下文
+ (UIImage *)cutImage:(UIImage *)image imageViewSize:(CGSize)size clipPoints:(NSArray *)points { //图片大小和实际显示大小的比例 CGFloat scale_width = image.size.width/size.width; CGFloat scale_height = image.size.height/size.height; //处理剪裁的点 NSArray *newPoints = [UIImage points:points scalex:scale_width scaleY:scale_height]; //确定上下左右边缘的点 //x升序数组 NSArray *point_x = [newPoints sortedArrayUsingComparator:^NSComparisonResult(NSValue *obj1, NSValue *obj2) { CGPoint point1 = [obj1 CGPointValue]; CGPoint point2 = [obj2 CGPointValue]; return point1.x > point2.x; }]; //y升序数组 NSArray *point_y = [newPoints sortedArrayUsingComparator:^NSComparisonResult(NSValue *obj1, NSValue *obj2) { CGPoint point1 = [obj1 CGPointValue]; CGPoint point2 = [obj2 CGPointValue]; return point1.y > point2.y; }]; //确定剪切的区域 CGRect clipRect = CGRectMake([point_x.firstObject CGPointValue].x, [point_y.firstObject CGPointValue].y, [point_x.lastObject CGPointValue].x - [point_x.firstObject CGPointValue].x, [point_y.lastObject CGPointValue].y - [point_y.firstObject CGPointValue].y); //开启图形上下文 UIGraphicsBeginImageContext(clipRect.size); UIBezierPath *path = [UIBezierPath bezierPath]; for (NSInteger i = 0; i < newPoints.count; i ++) { CGPoint point = [newPoints[i] CGPointValue]; if (i == 0) { [path moveToPoint:point]; } else { [path addLineToPoint:point]; } } [path closePath]; [path addClip]; //画图 [image drawAtPoint:CGPointMake(-clipRect.origin.x, -clipRect.origin.y)]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
原文作者:
作者:莫须有恋
链接:http://www.jianshu.com/p/3baddf100b67