ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪

一、矩阵操作 -  仿射变换

  • 缩放 void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
  • 旋转 void CGContextRotateCTM(CGContextRef c, CGFloat angle)
  • 平移 void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
#import "HMView.h"

@implementation HMView
- (void)drawRect:(CGRect)rect
{
    // 1.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // 矩阵操作
    //    Current graphics state's Transformation Matrix
    // 旋转
    //    CGContextRotateCTM(ctx, M_PI_4);
    // 缩放
    //    CGContextScaleCTM(ctx, 1, 0.5);
    // 平移
    //    CGContextTranslateCTM(ctx, 150, 150);

    // 2.拼接路径 同时 把路径添加到上下文当中
    //    CGContextAddArc(ctx, 150, 150, 100, 0, 2 * M_PI, 1);
    //    CGContextMoveToPoint(ctx, 0, 0);
    //    CGContextAddLineToPoint(ctx, 300, 300);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, 150, 150, 100, 0, 2 * M_PI, 1);
    CGPathMoveToPoint(path, NULL, 0, 0);
    CGPathAddLineToPoint(path, NULL, 300, 300);

    // 添加路径到上下文当中
    CGContextAddPath(ctx, path);

    // 设置线宽
    CGContextSetLineWidth(ctx, 10);

    // 3.渲染
    CGContextStrokePath(ctx);
}
@end

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第1张图片

 二、图形上下文栈的操作

0. 图形上下文栈是什么?

每一个“图形上下文”对象都包含一个“栈”结构,这个栈结构用来存储当前图形上下文的状态信息。(每个图形上下文对象中都包含:1>“图形状态”; 2> 路径信息; 3> 输出目标)

1. 为什么要学习图形上下文栈?

1. 第一次画图后修改了颜色, 后面的图形要再恢复到原来的颜色

2. 第一次画图的时候旋转了上下文, 后面的图形不要旋转

3. 第一次画图的时候修改了线宽,线头样式等,后面画图的时候不要这些样式,要默认的样子

总结:前面绘图的时候修改了上下文,后面绘图的时候要再次使用被修改前的上下文对象

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第2张图片

1、先绘制图形,设置颜色,线宽,旋转。

2、然后再绘制其他的图形。(其他图形默认也会使用相同的设置(颜色、线宽、旋转等))

解决:

1. 在第一次绘制图形前,保存上下文。

2. 在第二次绘制图形前,恢复上下文。

图形上下文栈的操作

将当前【图形上下文】中的“绘图状态”信息保存到“栈”中

void CGContextSaveGState(CGContextRef c) 

将栈顶的“绘图状态”出栈, 替换掉当前的“图形上下文”中的“绘图状态”

void CGContextRestoreGState(CGContextRef c)

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第3张图片   ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第4张图片

三、Quartz2D的内存管理

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第5张图片

  • 使用含有“Create”或“Copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露
  • 使用不含有“Create”或“Copy”的函数获取的对象,则不需要释放
  • 如果retain了一个对象,不再使用时,需要将其release掉
  • 可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。
  • 也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数
  • 演示通过CGMutablePathRef实现绘图。通过 Product -> Analyze 来进行静态分析。

使用Path 对象时的内存管理问题:

1> 凡是遇到 retain 、 copy 、 create 出的对象, 都需要进行 release

2> 但是CGPathCreateMutable()不是 OC 方法, 所以不是调用 某个对象的 release方法

3> CGXxxxxCreate 对应的就有 CGXxxxxRelease。

4> 通过 CFRelease(任何类型);可以释放任何类型。

四、绘制“文字”

通过 UIKit 框架来绘制

  • [str drawAtPoint:]  从某一个点开始绘制
  • [str drawInRect:]  绘制到指定的区域

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第6张图片    ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第7张图片

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第8张图片

删除背景颜色 可以让阴影的地方显示 文字

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第9张图片  ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第10张图片

将underlineStyleAttributeName 删掉 阴影直接消失     没有下划线参数就没有阴影 参数传为0 就没有下划线

五、绘制”图片”

UIImage *imgIcon = [UIImage imageNamed:@"002"];
    [imgIcon drawAtPoint:CGPointMake(20, 20)];
    [imgIcon drawInRect:rect];
    [imgIcon drawAsPatternInRect:rect];

 设置 UIView 的背景色为某个图片的屏幕效果。通过[UIColor colorWithXxxxxx:图片]来实现。

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第11张图片

六、自定义一个 View 模拟图片框

ViewController.M

#import "ViewController.h"
#import "HMImageView.h"

@interface ViewController ()

@property (nonatomic, weak) HMImageView* imageView;
//@property (nonatomic, weak) UIImageView* imageView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    HMImageView* imageView = [[HMImageView alloc] initWithImage:[UIImage imageNamed:@"me"]];
    self.imageView = imageView;
    [self.view addSubview:imageView];

    // -------
    //    HMImageView* imageView = [[HMImageView alloc] init];
    //    imageView.frame = CGRectMake(0, 0, 200, 200);
    //    imageView.image = [UIImage imageNamed:@"me"];
    //    self.imageView = imageView;
    //    [self.view addSubview:imageView];

    // *******
    //    UIImageView* imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"me"]];
    //    self.imageView = imageView;
    //    [self.view addSubview:imageView];
    
    //    // -------
    //    UIImageView* imageView = [[UIImageView alloc] init];
    //    imageView.frame = CGRectMake(0, 0, 200, 200);
    //    imageView.image = [UIImage imageNamed:@"me"];
    //    self.imageView = imageView;
    //    [self.view addSubview:imageView];
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    self.imageView.image = [UIImage imageNamed:@"Press"];
}

@end

HMImageView.M 

#import "HMImageView.h"

@implementation HMImageView
- (instancetype)initWithImage:(UIImage*)image{
    self = [super initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
    if (self) {
        self.image = image;
    }
    return self;
}
- (void)setImage:(UIImage*)image{
    _image = image;
    // 重绘
    [self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect{
    // 把传过来的图片绘制到屏幕上
    [self.image drawInRect:rect];
}
@end

设置 UIView 的背景为一张图片

1、通过[UIColor colorWithPatternImage:]实现

 2、通过绘制一张图片到 UIView 上实现

裁剪 只是裁剪上下文的显示区域  上下文本身依然存在且大小不变

七、图片裁剪

ios基础篇(七)—— 矩阵操作、图形上下文栈、Quartz2D的内存管理、绘制、图片裁剪_第12张图片

核心代码

void CGContextClip(CGContextRef c) 

将当前上下所绘制的路径裁剪出来(超出这个裁剪区域的都不能显示)

图片裁剪思路:

1》 在上下文中绘制一个要裁减的图形

2》调用void CGContextClip(CGContextRef c)进行裁剪

3》在裁剪好的上下文中再把图片绘制上去。(注意绘制图片的时候,必须绘制到已经裁剪出的图形位置,否则不显示)

在 UIView 上显示一个裁剪后的图片

1、获取 UIView 的图形上下文对象

2、在图形上下文对象上绘制一个圆形

3、执行裁剪操作(裁剪的意思是告诉系统,将来只有在被裁减出的区域内绘制的图形才会显示)

4、把图片绘制到上下文上(直接调用 UIImage 对象的绘图方法即可)

直接裁剪图片并保存

  • 1、加载要裁减的图片
  • 2、根据要裁剪的图片大小开启一个Bitmap 的图形上下文
  • 3、在这个图形上下文上绘制一个圆形(这个圆的圆心应为这个图形上下文的中心点,半径应为这个图形上下文的最短的边的一半)
  • 4、执行裁剪操作
  • 5、把图片绘制到当前的“图形上下文”中(因为这个图形上下文的大小是按照要裁减的图片的大小来创建的,所以绘图的时候直接从(0,0)开始绘制即可)
  • 6、从图形上下文中获取图片对象
  • 7、将图片对象转换为 NSData 类型UIImagePNGRepresentation(img)
  • 8、保存图片对象到目标位置(沙盒或者相册)

图片类型的图形上下文

#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView* imageView;
@end

@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    // 开启图片类型的图形上下文
    UIGraphicsBeginImageContext(CGSizeMake(300, 300));
    // 获取当前的上下文(图片类型)
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 拼接路径 同时 把路径添加上上下文当中
    CGContextMoveToPoint(ctx, 50, 50);
    CGContextAddLineToPoint(ctx, 100, 100);
    // 渲染
    //    CGContextStrokePath(ctx);
    // 通过图片类型的图形上下文 获取图片对象
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    // 关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    // 把获取到的图片 放到 图片框上
    self.imageView.image = image;
}

保存到沙盒

#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView* imageView;
@end
@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    // 开启图片类型的图形上下文
    UIGraphicsBeginImageContext(CGSizeMake(300, 300));
    // 获取当前的上下文(图片类型)
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 拼接路径 同时 把路径添加上上下文当中
    CGContextMoveToPoint(ctx, 50, 50);
    CGContextAddLineToPoint(ctx, 100, 100);
    // 渲染
    CGContextStrokePath(ctx);
    // 通过图片类型的图形上下文 获取图片对象
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext()
    // 关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    // 把获取到的图片 放到 图片框上
    self.imageView.image = image;
    // 获取 doc 路径
    NSString* docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    // 获取文件路径
    NSString* filePath = [docPath stringByAppendingPathComponent:@"xx.png"];
    // 1.把 image 对象转化成 nsdata
    //    NSData* data = UIImagePNGRepresentation(image);
    NSData* data = UIImageJPEGRepresentation(image, 0);
    //     2.通过 data 的 write to file 写入到沙盒中
    [data writeToFile:filePath atomically:YES];
}
@end

开启图片类型的上下文 with option

 UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), NO, [UIScreen mainscreen].scale);
 < == > UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), NO, 0);
第三个参数最重要 缩放因子  传0表示不缩放 即在不同手机的不同屏幕不缩放

获取裁剪过后的图片

#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView* imageView;
@end
@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    // 3.获取图片
    UIImage* image = [UIImage imageNamed:@"me"];
    // 1.开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    // 5.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 4.画一个裁剪的图片
    CGContextAddArc(ctx, image.size.width * 0.5, image.size.height * 0.5, image.size.width * 0.5, 0, 2 * M_PI, 1);
    // 6.裁剪
    CGContextClip(ctx);
    // 7.把图片画上去
    [image drawAtPoint:CGPointZero];
    // 8.取出来
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    // 2.关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    // 测试
    self.imageView.image = newImage;
}
@end

获取裁剪后的图片

#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView* imageView;
@end
@implementation ViewController
- (void)viewDidLoad{
    [super viewDidLoad];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    // 3.获取图片
    UIImage* image = [UIImage imageNamed:@"me"];
    // 1.开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    // 5.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 4.画一个裁剪的图片
    CGContextAddArc(ctx, image.size.width * 0.5, image.size.height * 0.5, image.size.width * 0.5, 0, 2 * M_PI, 1);
    // 6.裁剪
    CGContextClip(ctx);
    // 7.把图片画上去
    [image drawAtPoint:CGPointZero];
    // 8.取出来
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    // 2.关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    // 测试
    self.imageView.image = newImage;
    // 保存到相册
    UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), @"123123123");
}
// 保存到相册的回调
- (void)image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo{
    NSLog(@"保存完成 - %@", contextInfo);
}

裁剪一个带圆环的图片

  • // 加载要裁剪的图片    
  • // 创建一个比原始图片略大的基于 Bitmap 的“图形上下文”    
  • // 获取当前上下文    
  • // ------------------------------------ 开始绘制一个圆环    
  • / /确定圆心    

  • // 确定半径    

  • // 开始绘制圆环路径    

  • // 渲染 -------------------------------- 开始裁剪一个圆
  • // ------------------------------------ 开始绘制图片    
  • // 从绘图上下文中获取图片    
  • // 结束图形上下文    
  • // 保存到相册
  • // 保存到沙盒    
  • // 保存图片
- (void)viewDidLoad{
    [super viewDidLoad];
    // 3.获取图片
    UIImage* image = [UIImage imageNamed:@"me"];
    // 4.margin
    CGFloat margin = 20;
    // 5.计算图片类型的图形上下文的大小
    CGSize ctxSize = CGSizeMake(image.size.width + 2 * margin, image.size.height + 2 * margin);
    // 1.开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(ctxSize, NO, 0);
    // 6.获取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 8.计算圆心
    CGPoint arcCenter = CGPointMake(ctxSize.width * 0.5, ctxSize.height * 0.5);
    // 9.计算半径
    CGFloat radius = (image.size.width + margin) * 0.5;
    // 7.画圆环
    CGContextAddArc(ctx, arcCenter.x, arcCenter.y, radius, 0, 2 * M_PI, 1);
    // 10.设置宽度
    CGContextSetLineWidth(ctx, margin);
    // 11.渲染圆环
    CGContextStrokePath(ctx);
    // 12.画头像显示的区域
    CGContextAddArc(ctx, arcCenter.x, arcCenter.y, image.size.width * 0.5, 0, 2 * M_PI, 1);
    // 13.裁剪显示区域
    CGContextClip(ctx);
    // 14.画图片
    [image drawAtPoint:CGPointMake(margin, margin)];
    // 获取图片
    image = UIGraphicsGetImageFromCurrentImageContext();
    // 2.关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    // 保存到相册
    UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);
}

图片水印

水印:在图片上加的防止他人盗图的半透明logo、文字、图标

实现方式:利用Quartz2D,将水印(文字、LOGO)画到图片的右下角

核心代码

开启一个基于位图的图形上下文

void     UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) 

从上下文中取得图片

(UIImage) UIImage* UIGraphicsGetImageFromCurrentImageContext(); 

结束基于位图的图形上下文

void     UIGraphicsEndImageContext();

图片加水印基本思路

1、添加文字水印

1> 创建位图上下文

2> 把图片画上去

3> 把文字画上去

4>  从上下文中取出图片

2、添加图片水印

1> 创建位图上下文

2> 把图片画上去

3> 加载 logo 图片(水印图片),把水印图片也画上去

4>  从上下文中取出图片

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    // 3.获取图片
    UIImage* image = [UIImage imageNamed:@"scene"];
    // 1.开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    // 6.画大图
    [image drawAtPoint:CGPointZero];
    // 4.文字
    NSString* str = @"黑马13期";
    // 5.画文字水印
    [str drawAtPoint:CGPointMake(20, 20) withAttributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:20] }];
    // 7.图片
    UIImage* logo = [UIImage imageNamed:@"logo"];
    // 8.画图片水印
    [logo drawAtPoint:CGPointMake(image.size.width * 0.6, image.size.height * 0.7)];
    // 取图片
    image = UIGraphicsGetImageFromCurrentImageContext();
    // 保存到相册
    UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);
    // 2.关闭图片类型的图形上下文
    UIGraphicsEndImageContext();
    NSLog(@"test");
}

屏幕截图

核心代码

- (void)renderInContext:(CGContextRef)ctx;

调用某个view的layer的renderInContext:方法即可

截图基本思路:

1、获取控件的 layer 对象

2、调用 layer 对象的 renderInContext:方法渲染到上下文中

**注意:UISegmentedControl 渲染时有问题

- (void)viewDidLoad{
    // 开启图片类型的图形上下文
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
    // 获取当前的上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 截图 把view 的内容 放到上下文中 然后 渲染
    [self.view.layer renderInContext:ctx];
    // 取图片
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    // 关闭上下文
    UIGraphicsEndImageContext();
    // 保存到相册
    UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);
}
// --- 旋转缩放平移

// 对图形上下文进行旋转平移缩放的操作

// 缩放
// 第一个参数:需要缩放的上下文
// 第二个参数:x轴缩放的比例
// 第三个参数:y轴缩放的比例
CGContextScaleCTM(ctx, 1, 0.5);

// 平移
// 第一个参数:需要平移的上下文
// 第二个参数:x轴的偏移量
// 第三个参数:y轴的偏移量
CGContextTranslateCTM(ctx, 150, 150);

// 旋转
// 第一个参数:需要旋转的上下文
// 第二个参数:顺时针旋转的角度
CGContextRotateCTM(ctx, M_PI_4);

// --- 图形上下文栈

// 图形上下文栈 只是保存 状态信息(样式)

// 保存状态信息
CGContextSaveGState(ctx);

// 恢复状态信息
CGContextRestoreGState(ctx);

// --- quartz2d 内存管理
// 如果包含 create copy 关键字的时候 记得释放
// 释放 1
CGPathRelease(path);
// 释放 2
CFRelease(path);

// --- 绘制文字
// 绘制 - 从(0,0)点开始画
[str drawAtPoint:CGPointZero withAttributes:dict];

// 绘制 - 绘制到指定的区域
[str drawInRect:rect withAttributes:nil];

// AttributeName - key 在 UIKit下的 NSAttributeName.h 里面
// 个人建议 记其中一个

// shadow
NSShadow* s = [[NSShadow alloc] init];
s.shadowOffset = CGSizeMake(100, 100); // 偏移量
s.shadowBlurRadius = 0; // 越小越不模糊 高斯模糊
s.shadowColor = [UIColor yellowColor]; // 阴影的颜色

// --- 绘制图片
// 绘制 - 从某个点开始绘制
[image drawAtPoint:CGPointZero];
// 绘制 - 绘制到某一个区域
[image drawInRect:rect];
// 绘制 - 平铺
[image drawAsPatternInRect:rect]; // 可以考虑用来设置某个view的背景图片

// --- 裁剪上下文显示的区域
// 前提:画一个图形
// 裁剪图片
CGContextClip(ctx);

// 告诉系统 已这个图形来裁剪图片 渲染 然后显示出来
// 所谓裁剪并不是裁剪掉上下文 只是单纯的 裁剪出来希望显示的区域而已!!!

// --- bitmap上下文

// 创建上下文(图片)
UIGraphicsBeginImageContext(CGSizeMake(300, 300));
// 创建上下文 (大小,不透明,缩放:0)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0);

// 关闭上下文
UIGraphicsEndImageContext();

//  通过图片的图形上下文获取图片
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();

// 保存到沙盒当中
NSString* path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
path = [path stringByAppendingPathComponent:@"xx.png"];
// 把image转化成 NSData类型
NSData* data = UIImagePNGRepresentation(image);
NSLog(@"%ld", data.length);
// 然后在通过data对象  write to file 来写入到沙盒中
[data writeToFile:path atomically:YES];

// --- 裁剪圆形图片
// 保存到相册
// 第一个:图片
// 第二个 第三个 监听   注意:@selector 不能随便写 使用"注释"当中的方法
// 第四个: 可以把它当做一个tag来使用 参数在监听的方法当中会传入
UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image:didFinishSavingWithError:contextInfo:), @"hello1111");

// --- 屏幕截图
// 对控制器的view的layer属性 进行操作
[self.view.layer renderInContext:ctx];

 

你可能感兴趣的:(ios小白)