iOS核心笔记——Quartz 2D-Bitmap

1、Bitmap绘图简介:

✨重要:因为图片的输出目标为Bitmap,而不是输出到UIView上;在控制器中并没有已经创建好的Bitmap图形上下文,所以,需要我们手动创建Bitmap图形上下文。注意:一定要区分自定义控件时是通过获取storyboard中关联的UIView的图形上下文,因为自定义控件是将图形上下文中的目标图形绘制到UIView上,所以,需要获取UIView的图形上下文;将绘制信息缓存至UIView的图形上下文中。而将图形绘制到Bitmap中,因为图片的输出目标为Bitmap不再是UIView,而程序中并没有已经存在的Bitmap图形上下文;所以,我们应该手动创建Bitmap图形上下文,将水印图片的绘制信息保存至Bitmap图形上下文中;将来Bitmap可以根据图形上下文绘制好图形,我们才能从Bitmap中获取绘制好的水印图片。


2、Bitmap基本绘图:
2-1、裁剪成圆形图片:
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-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-3、屏幕截图:
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-4、制作水印图片:
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-5、保存至手机:
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-6、读取手机中的图片:
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,UIImagePickerControllerDelegate


2-7、擦除指定区域的图片:
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-8、截取指定区域的图片:
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.}

 

 

转载于:https://www.cnblogs.com/leilifengixng/p/6381732.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值