1. 程式人生 > >iOS 繪圖 (UIImage的一些操作)

iOS 繪圖 (UIImage的一些操作)

move 圖像 可能 ret render ast update 鏈接 net

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

iOS 繪圖 (UIImage的一些操作)