博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发 — Quartz 2D知识点应用 (制作了一个Demo,源代码)
阅读量:6213 次
发布时间:2019-06-21

本文共 10001 字,大约阅读时间需要 33 分钟。

hot3.png

欢迎关注我的新浪微博: @立里童立里

   通过Quartz 2D知识点制作了一个移动镜头的小Demo

  • 实现的功能:

  • 1. 移动镜头,如下图所示:

  • 231909_lU8w_2250033.png231909_p3BR_2250033.png

  • 2. 调节镜头大小,如下图所示:

  • 232338_7Q6p_2250033.png232338_EQ2M_2250033.png

  • 3. 调节速率,如图所示:(你觉得可能吗,展示不了,请看上图速度调节条)

  • 4. 显示全图,如下图所示(由于图片超过了200K所以改了下尺寸):

233957_OatF_2250033.png

  • 5. 隐藏全图,回到镜头画面

233957_Ufr3_2250033.png

  • 6. 裁剪图片(只保留镜头笑下的图片,并保存到本地),如图所示:

234755_Jn55_2250033.png

  • 7. 截取全图,如图所示:

        234647_mRzT_2250033.png

  • 8. 触摸停止或启动镜头,(无法展示,见谅)

源代码如下所示:

  • 文件截图

235501_DYxq_2250033.png

FYViewController.m 文件代码

#define FYColor(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a/1.0]#define FYSaveTruPath [NSString stringWithFormat:@"/Users/tongfangyuan/Desktop/truncation/truncation_image/tru_image_%i.png",self.imageCounts]#import "FYViewController.h"#import "UIImage+FY.h"#import "FYView.h"@interface FYViewController ()// 底部工具栏@property (nonatomic, strong) UIView *BottomView;// 图片@property (nonatomic, strong) UIImageView *iconView;// 全图按钮@property (nonatomic, strong) UIButton *wholeBtn;@property (nonatomic, assign, getter = isShowImage) BOOL showImage;// 截图按钮@property (nonatomic, strong) UIButton *truncationBtn;// 保存截图模式@property (nonatomic, assign, getter = isTruncation) BOOL truncation;// FYView@property (strong, nonatomic) IBOutlet FYView *searchView;// 截图张数@property (nonatomic, assign) int imageCounts;@end@implementation FYViewController- (void)viewDidLoad{    [super viewDidLoad];    // 设置背景图片    _iconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"luffy"]];       self.view.backgroundColor = [UIColor blackColor];        // 1. 创建底部工具栏View    _BottomView = [[UIView alloc]init];    _BottomView.backgroundColor = FYColor(201, 201, 201, 1);    _BottomView.frame = CGRectMake(0, FYScreenH - FYDefaultH, FYScreenW, FYDefaultH);    [self.view addSubview:_BottomView];        // 2. 创建全图按钮(打开或关闭全图按钮)    _wholeBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, FYScreenW / 2, FYDefaultH)];    _wholeBtn.backgroundColor = [UIColor blueColor];    [_wholeBtn setTitle:@"显示全图" forState:UIControlStateNormal];    [_wholeBtn addTarget:self action:@selector(showWholeImage:) forControlEvents:UIControlEventTouchUpInside];    _showImage = YES;    [self.BottomView addSubview:_wholeBtn];        // 3. 创建截图按钮    _truncationBtn = [[UIButton alloc] initWithFrame:CGRectMake(FYScreenW / 2, 0, FYScreenW / 2, FYDefaultH)];    [_truncationBtn setTitle:@"裁剪图片" forState:UIControlStateNormal];    [_truncationBtn addTarget:self action:@selector(truncationPicture) forControlEvents:UIControlEventTouchUpInside];    _truncation = NO;    [self.BottomView addSubview:_truncationBtn];    }// 截取屏幕- (void)truncationPicture{        if (self.isTruncation) {    // 截屏模式                // 截取全图        [self saveFullImage];            } else {                    // 裁剪模式                // 裁剪镜头下的图片        [self.searchView clipImage];            }        }/** *  截取全图 */- (void)saveFullImage{        // 1. 截图    CGSize size = CGSizeMake(FYScreenW, FYScreenH - FYDefaultH);    UIImage *newImage = [UIImage imageByTruncationInView:self.view WithSize:size];        // 2. 截屏计数器+1,保存图片    self.imageCounts++;    NSData *data = UIImagePNGRepresentation(newImage);    [data writeToFile:FYSaveTruPath atomically:YES];}// 显示或隐藏全图事件- (void)showWholeImage:(id)sender {        if (self.isShowImage) {     // 展开全图,停止镜头                // 1. 显示全图        [self showImage];                // 2. 更改两个按钮的主题        [_wholeBtn setTitle:@"隐藏全图" forState:UIControlStateNormal];        [_truncationBtn setTitle:@"截取全图" forState:UIControlStateNormal];                // 3. 更改模式        _showImage = NO;        _truncation = YES;    } else {                    // 关闭全图, 移动镜头                // 1. 隐藏全图        [self closeImage];                // 2. 更改两个按钮的主题        [_wholeBtn setTitle:@"显示全图" forState:UIControlStateNormal];        [_truncationBtn setTitle:@"裁剪图片" forState:UIControlStateNormal];                // 3. 更改模式        _showImage =YES;        _truncation = NO;            }    }/** *  显示全图 */- (void)showImage{    // 1. 显示全图    _iconView.frame = CGRectMake(0, 0, 0, FYScreenH - FYDefaultH);    [UIView animateWithDuration:1 animations:^{        _iconView.frame = CGRectMake(0, 0, FYScreenW, FYScreenH - FYDefaultH);    }];    [self.view addSubview:_iconView];     _iconView.userInteractionEnabled = NO;        // 2. 镜头停止滚动    [self.searchView stopScroll:nil];}/** *  隐藏全图 */- (void)closeImage{        // 1. 隐藏全图    _iconView.frame = CGRectMake(0, 0, FYScreenW, FYScreenH - FYDefaultH);    [UIView animateWithDuration:1 animations:^{                _iconView.frame = CGRectMake(FYScreenW, 0, 0, FYScreenH - FYDefaultH);            } completion:^(BOOL finished) {                [self.searchView stopScroll:nil];            }];     _iconView.userInteractionEnabled = NO;}// 隐藏状态栏- (BOOL)prefersStatusBarHidden{    return YES;}@end

  • FYView.h 文件代码:

#import 
@interface FYView : UIView// 点击控制圆圈移动或停止- (void)stopScroll:(id)sender;// 裁剪图片- (void)clipImage;@end

  • FYView.m 文件代码:

#import "FYView.h"#import "UIImage+FY.h"#define FYImageRect CGRectMake(0, 0, FYScreenW, FYScreenH - FYDefaultH)#define FYSaveClipPath [NSString stringWithFormat:@"/Users/tongfangyuan/Desktop/truncation/clip_Image/clip_image_%i.png",self.imageCounts]@interface FYView ()// 保存圆圈坐标,直径, 移动距离@property (nonatomic, assign) CGFloat centerX;@property (nonatomic, assign) CGFloat centerY;@property (nonatomic, assign) CGFloat diameter;@property (nonatomic, assign) CGFloat moveDis;// 截图张数@property (nonatomic, assign) int imageCounts;// 保存累加值@property (nonatomic, assign) int countX;@property (nonatomic, assign) int countY;// 保存计时器状态@property (nonatomic, assign, getter = isTimerOn) BOOL timerOn;// 创建一个定时器@property (nonatomic, strong) NSTimer *timer;// 直径滑动条@property (weak, nonatomic) IBOutlet UISlider *mySlider;;// 速度滑动条@property (weak, nonatomic) IBOutlet UISlider *SpeedSlider;// 改变直径- (IBAction)changeMyRadius:(UISlider *)sender;// 改变速度- (IBAction)changeSpeed:(UISlider *)sender;@end@implementation FYView// moveDis(直径) get方法- (CGFloat)moveDis{    _moveDis = self.SpeedSlider.value;        return _moveDis;}// diameter(移动距离) get 方法- (CGFloat)diameter{    _diameter = self.mySlider.value;        [self setNeedsDisplay];    return _diameter;}- (void)drawRect:(CGRect)rect{    // 获取当前上下文    CGContextRef ref = UIGraphicsGetCurrentContext();            // 创建上下文栈    CGContextSaveGState(ref);    CGContextAddEllipseInRect(ref, CGRectMake(self.centerX, self.centerY, self.diameter, self.diameter));        // 裁剪函数    CGContextClip(ref);        // 渲染    CGContextStrokePath(ref);        // 创建一个图片    UIImage *iconImage = [UIImage imageNamed:@"luffy"];    [iconImage drawInRect:FYImageRect];        // 恢复默认属性    CGContextRestoreGState(ref);        // 再一次渲染    CGContextStrokePath(ref); [self addTimer];    [self addTimer];}/** *  裁剪 */- (void)clipImage{    // 创建图片    UIImage *image = [UIImage imageNamed:@"luffy"];        // 裁剪图片    CGRect rect = CGRectMake(self.centerX, self.centerY, self.diameter, self.diameter);    UIImage *newImage = [UIImage imageWithClipImage:image inRect:rect];        // 存入数据    NSData *data = UIImagePNGRepresentation(newImage);    self.imageCounts++;    [data writeToFile:FYSaveClipPath atomically:YES];    }/** *  移动镜头 */- (void)searchImage{        // 判断X坐标位置    if (self.centerX <= 0) { // 到达最右边,圆圈X坐标减少                _countX = self.moveDis;    } else if (self.centerX >= FYScreenW - self.diameter){                // 到达最左边,圆圈X坐标增加         _countX = - self.moveDis;    }        // 判断Y坐标位置    if (self.centerY <= 0) { // 到达最底部, 圆圈Y坐标减少                _countY = self.moveDis;    } else if (self.centerY >= FYScreenH - self.diameter - FYDefaultH){                // 到达最顶部, 圆圈Y坐标增加        _countY = - self.moveDis;    }        _centerX += _countX;    _centerY += _countY;    [self setNeedsDisplay];}/* 触摸启动或停止计时器 */- (void)stopScroll:(id)sender {        if (self.isTimerOn) {        [self removeTimer];    } else {        self.superview.backgroundColor =  [UIColor whiteColor];        [self addTimer];    }    }/** *  改变圆的直径 */- (IBAction)changeMyRadius:(UISlider *)sender {            self.diameter = sender.value;    }/** *  改变圆移动的速度 */- (IBAction)changeSpeed:(UISlider *)sender {        self.moveDis = sender.value;}/** *  添加计时器 */- (void)addTimer{    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.00025 target:self selector:@selector(searchImage) userInfo:nil repeats:NO];    self.timerOn = YES;}/** *  移除计时器 */- (void)removeTimer{    self.timerOn = NO;    [self.timer invalidate];    self.timer = nil;}@end

  • UIImage+FY.h 文件代码如下:

#import 
#define FYScreenW 320#define FYScreenH 480#define FYDefaultH 44#define FYImageRect CGRectMake(0, 0, FYScreenW, FYScreenH - FYDefaultH)@interface UIImage (FY)/** *  裁剪图片 */+ (UIImage *)imageWithClipImage:(UIImage *)image inRect:(CGRect)rect;/** *  截取屏幕 */+ (UIImage *)imageByTruncationInView:(UIView *)view WithSize:(CGSize)size;@end

  • UIImage+FY.m 文件代码如下:

#import "UIImage+FY.h"@implementation UIImage (FY)/** *  裁剪图片 */+ (UIImage *)imageWithClipImage:(UIImage *)image inRect:(CGRect)rect{    // 创建上下文    CGSize size = CGSizeMake(FYScreenW, FYScreenH - FYDefaultH);    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);        // 获取当前上下文    CGContextRef ref = UIGraphicsGetCurrentContext();        CGContextAddEllipseInRect(ref, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));        // 执行裁剪    CGContextClip(ref);        [image drawInRect:FYImageRect];        // 获取裁剪后的图片    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();        // 结束上下文    CGContextStrokePath(ref);        return newImage;}/** *  截取屏幕 */+ (UIImage *)imageByTruncationInView:(UIView *)view WithSize:(CGSize)size{    // 1. 创建上下文    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);        // 2. 调取方法截屏    [view.layer renderInContext:UIGraphicsGetCurrentContext()];        // 3. 获得截取的图片    UIImage *newIamge = UIGraphicsGetImageFromCurrentImageContext();        // 4. 渲染    UIGraphicsEndImageContext();        return newIamge;}@end

  • 控件连线图:

000534_sITu_2250033.png

提示:这个button是一个全透明的铺满屏幕的按钮(用来实现触摸停止或启动镜头功能)其 rect为 

CGRectMake(0, 0, 320, 480); // 全透明,铺满屏幕的按钮

  000534_ORja_2250033.png

001005_336i_2250033.png

----------------------------------------

兴趣驱动iOS开发

转载于:https://my.oschina.net/tong0842/blog/325530

你可能感兴趣的文章
功能测试的国别差异(日本与欧美)
查看>>
MPLS-聚合路由对LSP的破坏--高级feature
查看>>
 HTTP头信息解读
查看>>
如何定义IE的文档兼容模式
查看>>
在KEIL中使用MDK-ARM开发cortex-m4
查看>>
性价比更高的一套电脑配置
查看>>
我的友情链接
查看>>
ToRPC:一个双向RPC的Python实现
查看>>
Android 热修复
查看>>
Android:UI控件RatingBar、SeekBar、ProgressBar、RadioGroup、RadioButton、CheckBox、TextView
查看>>
NodeJS学习第一季-安装与介绍
查看>>
linux设备驱动中的并发控制——自旋锁
查看>>
JavaScript—script标签放在body里还是header里(25)
查看>>
【腾讯优测干货分享】如何降低App的待机内存(三)——探索内存增长的原因...
查看>>
Linux服务器下安装Composer 并使用Composer安装Thinkphp5.1
查看>>
centos 6.5 安装pip
查看>>
i/o监控
查看>>
我的友情链接
查看>>
centos7上安装open***
查看>>
明佳妈妈新营销谈要做好微博营销需要注意什么?
查看>>