iOS核心筆記——Quartz 2D-Bitmap

一、Bitmap繪圖簡介:

✨重要:由於圖片的輸出目標爲Bitmap,而不是輸出到UIView上;在控制器中並無已經建立好的Bitmap圖形上下文,因此,須要咱們手動建立Bitmap圖形上下文。注意:必定要區分自定義控件時是經過獲取storyboard中關聯的UIView的圖形上下文,由於自定義控件是將圖形上下文中的目標圖形繪製到UIView上,因此,須要獲取UIView的圖形上下文;將繪製信息緩存至UIView的圖形上下文中。而將圖形繪製到Bitmap中,由於圖片的輸出目標爲Bitmap再也不是UIView,而程序中並無已經存在的Bitmap圖形上下文;因此,咱們應該手動建立Bitmap圖形上下文,將水印圖片的繪製信息保存至Bitmap圖形上下文中;未來Bitmap能夠根據圖形上下文繪製好圖形,咱們才能從Bitmap中獲取繪製好的水印圖片。緩存


二、Bitmap基本繪圖:

2-一、裁剪成圓形圖片:
OC語言方式:
1./**
2. 裁剪成圓形圖片
3. */
4.- (void)clipImage{
5.    UIImage *image = [UIImage imageNamed:@"girl1"];
6.
7.    // 1. 開啓位圖圖形上下文
8.    UIGraphicsBeginImageContext(image.size);
9.    // 2. 獲取圖形上下文, 可省略
10.    //    CGContextRef ctx = UIGraphicsGetCurrentContext();
11.    // 3. 設置裁剪範圍, 注意: 此時是以位圖圖形上下文爲參考座標系
12.    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.height, image.size.height)];
13.    // 4. 裁剪
14.    [path addClip];
15.    // 5. 繪製圖片
16.    [image drawAtPoint:CGPointZero];
17.    // 6. 獲取裁剪後的圖片
18.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
19.    // 7. 更新imageView
20.    self.imageView.image = newImage;
21.    // 8. 關閉圖形上下文
22.    UIGraphicsEndImageContext();
23.}

 


 
C語言方式:
1.- (void)drawRect:(CGRect)rect{
2.    // 1. 獲取圖形上下文
3.    CGContextRef ctx = UIGraphicsGetCurrentContext();
4.
5.    // 2. 設置裁剪區域
6.    CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50));
7.
8.    CGContextClip(ctx);  // 裁剪view, 使view中只有裁剪區域能顯示
9.
10.    // 3. 顯示圖片
11.    UIImage *image = [UIImage imageNamed:@"me"];
12.    [image drawAtPoint:CGPointMake(100, 100)];
13.
14.    // 4. 渲染其餘圖形(使用裁剪後的的圖形上下文, 只能在指定區域顯示圖形)
15.    CGContextAddRect(ctx, CGRectMake(0, 0, 100, 100));
16.    CGContextFillPath(ctx);  // 渲染無效,圖形上下文中已經設置裁剪區域只能在指定區域顯示內容
17.}

 

 

2-二、裁剪帶有圓環的圖片:
OC語言方式:
1.- (void)viewDidLoad {
2.    [super viewDidLoad];
3.
4.    UIImage *image = [UIImage imageNamed:@"girl1"];
5.
6.    // 1. 開啓位圖圖形上下文
7.    UIGraphicsBeginImageContext(CGSizeMake(imageWidth, imageWidth));
8.    // 2. 裁剪外環
9.    UIBezierPath *path1 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, imageWidth, imageWidth)];
10.    [path1 addClip];
11.    [[UIColor redColor] set];
12.    [path1 fill];
13.
14.    // 3. 設置裁剪範圍, 注意: 此時是以位圖圖形上下文爲參考座標系
15.    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(imageWidth * 0.5, imageWidth * 0.5) radius:(imageWidth * 0.5) - 10 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
16.    // 4. 裁剪
17.    [path2 addClip];
18.    // 5. 繪製圖片
19.    [image drawAtPoint:CGPointMake(10, 10)];
20.    // 6. 獲取裁剪後的圖片
21.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
22.    // 7. 更新imageView
23.    self.imageView.image = newImage;
24.    // 8. 關閉圖形上下文
25.    UIGraphicsEndImageContext(); 
26.}

 

 

C語言方式:
1.    UIImage *oldImage = [UIImage imageNamed:@"me"];
2.
3.    // MARK: - 繪製大圓
4.    CGFloat borderW = 2;
5.    CGFloat circleRaduis = oldImage.size.width * 0.5 + borderW;
6.    CGFloat borderX = circleRaduis;
7.    CGFloat borderY = borderX;
8.
9.    // 1. 開啓Bitmap圖形上下文
10.    CGFloat bitmapWidth = circleRaduis * 2;
11.    CGSize bitmapSize = CGSizeMake(bitmapWidth, bitmapWidth);
12.    UIGraphicsBeginImageContextWithOptions(bitmapSize, NO, 0.0);
13.
14.    // 2. 獲取圖形上下文
15.    CGContextRef ctx = UIGraphicsGetCurrentContext();
16.
17.    CGContextAddArc(ctx, borderX, borderY, circleRaduis, 0, M_PI * 2, 0);
18.    [[UIColor whiteColor] setFill];
19.    // 1. 渲染
20.    CGContextFillPath(ctx);
21.
22.    // MARK: - 繪製小圓
23.    CGFloat smallX = borderX;
24.    CGFloat smallY = borderY;
25.    CGFloat smallRaduis = circleRaduis - borderW;
26.
27.    CGContextAddArc(ctx, smallX, smallY, smallRaduis, 0, M_PI * 2, 0);
28.
29.    // 1. 裁剪
30.    CGContextClip(ctx);
31.
32.    // 2. 繪製
33.    [oldImage drawAtPoint:CGPointMake(borderW, borderW)];
34.
35.    // 6. 獲取圖片
36.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
37.    self.iconView.image = newImage;
38.
39.    // 7. 關閉
40.    UIGraphicsEndImageContext();

 

 

2-三、屏幕截圖:
1.    // MARK: - 屏幕截圖
2.    // 1. 開啓圖形上下文
3.    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
4.
5.    // 2. 獲取圖形上下文
6.    CGContextRef ctx = UIGraphicsGetCurrentContext();
7.
8.    // 3. 將view中的layer渲染到圖形上下文中
9.    [self.view.layer renderInContext:ctx];
10.
11.    // 4. 獲取圖片
12.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
13.
14.    // 5. 壓縮成PNG格式圖片
15.    NSData *data = UIImagePNGRepresentation(newImage);
16.
17.    // 6. 寫到桌面
18.    [data writeToFile:@"/Users/hehuafeng/Desktop/abc.png" atomically:YES];
19.
20.    // 7. 關閉圖形上下文
21.    UIGraphicsEndImageContext();

 

 

1.- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
2.    //[UIScreen mainScreen].scale 設備點與像素座標的比例.
3.
4.    //1.開啓一個位圖上下文
5.  //UIGraphicsBeginImageContext(self.view.bounds.size);
6.
7.    //opaque:不透明度
8.    //縮放比例
9.    //0 = [UIScreen mainScreen].scale
10.    //scale:縮放比例.
11.    //在C語言當中不會進行像素與點的轉換.
12.    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
13.
14.    //2.獲取當前的上下文.
15.    CGContextRef ctx =  UIGraphicsGetCurrentContext();
16.
17.    //3.把View的內容繪製到上下文當中.
18.    [self.view.layer renderInContext:ctx];
19.
20.    //4.從上下文當中生成一張圖片
21.    UIImage *newImage =  UIGraphicsGetImageFromCurrentImageContext();
22.
23.    //5.關閉上下文
24.    UIGraphicsEndImageContext();
25.
26.    //把圖片寫入到電腦當中.(與電腦之間進行傳輸數據都是以二進制流形式傳輸)
27.    //把圖片轉成二進制流
28.    //NSData *data =  UIImageJPEGRepresentation(newImage, 1);
29.    NSData *data = UIImagePNGRepresentation(newImage);
30.    [data writeToFile:@"/Users/xiaomage/Desktop/newImage.png" atomically:YES];
31.}

 

 

2-四、製做水印圖片:
1.- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
2.    UIImage *backImage = [UIImage imageNamed:@"scene"];
3.    UIImage *logoImage = [UIImage imageNamed:@"logo"];
4.
5.    // 1. 建立Bitmap(位圖)圖形上下文(至關於建立UIImage對象, 開啓位圖圖形上下文, 無需接收)
6.    // CGSize size : 未來Bitmap(位圖)的實際大小
7.    // BOOL opaque : 不透明度
8.    // CGFloat scale : 縮放比, 官方建議使用0.0
9.    UIGraphicsBeginImageContextWithOptions(backImage.size, YES, 0.0);
10.
11.    // 2. 繪製背景圖片
12.    CGFloat backImageX = 0;
13.    CGFloat backImageY = 0;
14.    CGFloat backImageW = backImage.size.width;
15.    CGFloat backImageH = backImage.size.height;
16.
17.    [backImage drawInRect:CGRectMake(backImageX, backImageY, backImageW, backImageH)];
18.
19.    // 3. 繪製水印圖片
20.    CGFloat margin = 8;
21.    CGFloat scale = 0.1;
22.
23.    CGFloat logoImageW = backImageW * scale;
24.    CGFloat logoImageH = backImageH * scale;
25.    CGFloat logoImageX = backImageW - logoImageW - margin;
26.    CGFloat logoImageY = backImageH - logoImageH - margin;
27.
28.    [logoImage drawInRect:CGRectMake(logoImageX, logoImageY, logoImageW, logoImageH)];
29.
30.    // 4. 從Bitmap中獲取圖片
31.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
32.    self.imageView.image = newImage;
33.
34.    // 5. 關閉圖形上下文
35.    UIGraphicsEndImageContext();
36.
37.    // 6. 將圖片壓縮成PNG格式
38.    NSData *data = UIImagePNGRepresentation(newImage);
39.
40.    NSString *path = @"/Users/hehuafeng/Desktop/water.png";
41.    [data writeToFile:path atomically:YES];
42.}

 

 

2-五、保存至手機:
1./**
2. 將圖片保存至相機
3. */
4.- (void)saveToPhoto{
5.    // 1. 開啓位圖圖形上下文
6.    UIGraphicsBeginImageContext(self.view.bounds.size);
7.    CGContextRef ctx = UIGraphicsGetCurrentContext();
8.
9.    // 2. 渲染
10.    [self.imageView.layer renderInContext:ctx];
11.
12.    // 3. 獲取圖片
13.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
14.
15.    // 3. 保存至手機
16.    UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), @"哈哈");
17.
18.    // 4. 關閉位圖圖形上下文
19.    UIGraphicsEndImageContext();
20.}
21.
22./**
23. 將相片保存至手機必須實現的相應方法
24. */
25.- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
26.    NSLog(@"%@", contextInfo);
27.}

 

 

2-六、讀取手機中的圖片:
1.//照片
2.- (IBAction)photo:(id)sender {
3.    //彈出系統的相冊
4.    UIImagePickerController *pickVC = [[UIImagePickerController alloc] init];
5.
6.    //設置照片的來源
7.    pickVC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
8.
9.    pickVC.delegate = self;
10.
11.    [self presentViewController:pickVC animated:YES completion:nil];
12.    //[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:pickVC animated:YES completion:nil];
13.    //從中選擇照片
14.    //把照片繪製到畫板當中.
15.}
16.
17.#pragma -mark UIImagePickerController代理方法 當選擇照片完畢時調用.
18.- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
19.
20.    NSLog(@"%@",info);
21.    UIImage *image = info[UIImagePickerControllerOriginalImage];
22.
23.    NSData *data = UIImageJPEGRepresentation(image, 0);
24.    [data writeToFile:@"/Users/xiaomage/Desktop/image.jpg" atomically:YES];
25.
26.    //關閉照片選擇器
27.    [self dismissViewControllerAnimated:YES completion:nil]; 
28.}

 

 

✨重要:須要遵照這兩個協議才能使用圖片選擇器的代理,UINavigationControllerDelegate,UIImagePickerControllerDelegateui


2-七、擦除指定區域的圖片:
1./**
2. 拖拽手勢監聽方法
3. */
4.- (IBAction)pan:(UIPanGestureRecognizer *)pan {
5.    // 1. 開啓位圖圖形上下文
6.    UIGraphicsBeginImageContext(self.view.bounds.size);
7.    // 2. 獲取位圖圖形上下文
8.    CGContextRef ctx = UIGraphicsGetCurrentContext();
9.
10.    // MARK: - 繪製背景圖片必定要在渲染以前, 不然沒法達到疊加效果
11.    UIImage *image = [UIImage imageNamed:@"girl3"];
12.    [image drawInRect:self.view.bounds];
13.
14.    // 3. 將imageView中的內容渲染到圖形上下文中
15.    [self.imageView.layer renderInContext:ctx];
16.
17.    // 4. 設置區域
18.    CGPoint currentPoint = [pan locationInView:self.imageView];
19.    CGRect rect = CGRectMake(currentPoint.x - 15, currentPoint.y - 15, 30, 30);
20.    // 5. 進行擦除
21.    CGContextClearRect(ctx, rect);
22.
23.    // 6. 獲取新圖片
24.    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
25.
26.    // 7. 設置到imageView
27.    self.imageView.image = newImage;
28.
29.    // 8. 關閉圖形上下文
30.    UIGraphicsEndPDFContext();
31.}

 

 

2-八、截取指定區域的圖片:
1.- (IBAction)pan:(UIPanGestureRecognizer *)pan {
2.    // MARK: - 判斷手勢狀態
3.    if (pan.state == UIGestureRecognizerStateBegan) {
4.        // MARK. 獲取觸摸點
5.        CGPoint point = [pan locationInView:self.imageView];
6.        self.point = point;
7.
8.    }else if(pan.state == UIGestureRecognizerStateChanged){
9.        // MARK. 獲取當前點
10.        CGPoint currentPoint = [pan locationInView:self.imageView];
11.        CGFloat width = currentPoint.x - self.point.x;
12.        CGFloat height = currentPoint.y - self.point.y;
13.        self.coverView.frame = CGRectMake(self.point.x, self.point.y, width, height);
14.
15.    }else if (pan.state == UIGestureRecognizerStateEnded){
16.        // MARK - 確保imageView顯示的圖片與屏幕座標一致
17.        // 1. 開啓位圖圖形上下文並獲取
18.        UIGraphicsBeginImageContext(self.view.bounds.size);
19.        CGContextRef ctx = UIGraphicsGetCurrentContext();
20.
21.        // 2. 設置裁剪區域
22.        UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.coverView.frame];
23.        [path addClip];  // 裁剪
24.
25.        // 3. 截取屏幕
26.        [self.imageView.layer renderInContext:ctx];
27.        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
28.
29.        // 4. 更新imageView顯示的圖片, 確保圖片座標與屏幕座標一致
30.        self.imageView.image = newImage;
31.        // 5. 關閉位圖圖形上下文
32.        UIGraphicsEndImageContext();
33.
34.        // 6. 移除
35.        [self.coverView removeFromSuperview];
36.    } 
37.}
相關文章
相關標籤/搜索