iOS绘图 - UIImage的一些简单操作

DenVerjus 7年前
   <p>在 iOS绘图 - 基础篇 中我们知道有一种获取上下文的方法是UIGraphicsBeginImageContextWithOptions,本文主要在图片类型上下文中对图片进行操作,具体实现的功能:</p>    <pre>  <code class="language-objectivec">- 1.生成图片  - 2.绘制图片到视图  - 3.添加水印  - 4.截取屏幕或者相应view  - 5.图片擦除  - 6.图片裁剪</code></pre>    <ul>     <li>具体的方法使用就在方法的介绍中解释吧,为了代码的复用,对上述方法进行了封装,放在UIImage的类别中,方便今后使用。</li>    </ul>    <h2>图片操作的基本步骤</h2>    <pre>  <code class="language-objectivec">1.开启图形上下文  2.绘制图片  - 使用drowInRect或者drawAtPoint绘制图片(区别在哪儿?你可以先想一想)   drawInRect是以rect作为图片绘制的区域,图片是以填充的方式被绘制在当前区域图片的大小,rect的宽高比和原图片的宽高比不同时会造成图片的变形   drowAtPoint是以point作为图片绘制的起点,绘制的图片的大小依然是原图片的大小,不会使图片变形  - 将layer渲染在当前上下文  3.从当前上下文获取新的图片  4.关闭上下文</code></pre>    <h3>1.生成图片,这里我们生成特定颜色的图片</h3>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <h3>2.绘制图片,可以设置绘制的图片比例或者指定压缩后的图片的大小,可以当做压缩图片使用</h3>    <pre>  <code class="language-objectivec">这里我使用了drawInRect有兴趣的可以使用drowAtPoint,看看效果</code></pre>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <h3>3.绘制水印</h3>    <p>文字水印</p>    <p>可能你在添加文字水印之后,显示文字字体并不是你设置的字体大小,这是因为画布的size是图片的size,绘制后的图片被添加到ImageView上时可能被压缩或者放大,文字也就会发生变化。</p>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <p>图片水印</p>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <h3>4.截屏</h3>    <pre>  <code class="language-objectivec">1.创建图形上下文  2.将view的layer渲染到图形上下文  3.从图形上下文得到图片  4.关闭图像上下文</code></pre>    <p>//当然如果你只是需要某个view的快照,在iOS7之后你可以使用[view snapshotViewAfterScreenUpdates:NO];来获得,比如实现长按拖拽cell的操作</p>    <pre>  <code class="language-objectivec">+ (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);  }</code></pre>    <h3>5.擦除</h3>    <p>1.设置两张图片,上方为我们要擦除的图片,后方为需要展示的图片</p>    <p>2.设置擦除的区域的大小和位置</p>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/aa9a5e7a48d910cacf767323bb451571.gif"></p>    <p style="text-align:center">擦除</p>    <h3>6.图片裁剪</h3>    <p>矩形区域的裁剪,这里我们就利用drowAtPoint的特性去进行裁剪</p>    <p>1.假设一张图片的size是(600,600)</p>    <p>2.imageView的size是(300,300)</p>    <p>3.我们选择的裁剪区域是(10,10,150,150)</p>    <p>4.而我们为了能够保持原来图片的分辨率,在图片不拉伸的情况下在原图片上进行剪裁,所以实际我们在图片上的剪裁区域就是(20,20,300,300)</p>    <p>5.图片绘制在画布上的点就是(-20,-20),这样我们不需要进行裁剪就能获得我们想要得到的图片啦</p>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <p>自定义点连线截图</p>    <p>1.将自定义点变换到在图片上的点</p>    <p>2.计算出自定义点所在的区域rect</p>    <p>3.开始图形上下文,rect.size</p>    <p>4.绘制path,机型剪裁</p>    <p>5.绘图drawAtPoint,x: - rect.origin.x y: - rect.origin.y</p>    <p>6.从图形上下文获取图片</p>    <p>7.关闭图形上下文</p>    <pre>  <code class="language-objectivec">+ (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;  }</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6454cd96efcf07f9fd101613e6ad74ae.png"></p>    <p style="text-align:center">cutImage</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/3baddf100b67</p>    <p> </p>