iOS开发-图片上涂鸦绘制撤销功能

news2024/11/16 0:05:01

iOS开发-图片上涂鸦绘制撤销功能

当我们需要重新在图片上进行绘制涂鸦生成新的图,这里使用到了Graphics中的API功能。
Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。
在这里插入图片描述
微信搜索小游戏《全民保卫地球》玩玩吧,lets go

一、涂鸦绘制流程

使用涂鸦绘制使用Graphics,涂鸦流程如下

  • UIGraphicsBeginImageContextWithOptions 开始截图的方法
  • UIGraphicsGetCurrentContext 获取当前上下文
  • CGContextSetLineWidth 设置画笔宽度
  • CGContextSetStrokeColor 设置画笔颜色
  • CGContextSetLineCap 设置LineCap
  • CGContextMoveToPoint 移动到开始点
  • CGContextAddLineToPoint 添加line到目的point
  • CGContextStrokePath 把路径绘制到上下文
  • UIGraphicsGetImageFromCurrentImageContext 获得UIImage
  • UIGraphicsEndImageContext 关闭图片上下文

代码如下

-(void)drawLine:(CGPoint)from to:(CGPoint)to
{
    CGSize size = _drawingView.frame.size;
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    [self.drawingView.image drawAtPoint:CGPointZero];
    
    CGContextSetLineWidth(context, self.strokeWidth);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    CGContextSetLineCap(context, kCGLineCapRound);
    
    // 橡皮擦
    if(self.erasered){
        CGContextSetBlendMode(context, kCGBlendModeClear);
    }
    
    CGContextMoveToPoint(context, from.x, from.y);
    CGContextAddLineToPoint(context, to.x, to.y);
    CGContextStrokePath(context);
    
    self.drawingView.image = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
}
    

Graphics中还有更多其他API,可以尝试一下。上面的代码进行从from点到to点根据画笔颜色及宽度绘制线条,获得新的图

二、涂鸦手势移动实现绘制

在图片上进行涂鸦,我们需要UIPanGestureRecognizer来实现。UIGestureRecognizer是UIKit框架中的一个基类,用于识别并响应用户的手势操作。

在图片上添加手

定义变量

{
    CGPoint _prevDraggingPosition;
    CGSize _originalImageSize;
}
- (UIImageView *)drawingView {
    if (!_drawingView) {
        _drawingView = [[UIImageView alloc] initWithFrame:CGRectZero];
        
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(drawingViewDidPan:)];
        panGesture.maximumNumberOfTouches = 1;
        
        _drawingView.userInteractionEnabled = YES;
        [_drawingView addGestureRecognizer:panGesture];
    }
    return _drawingView;
}
    

实现手势事件
每次手势状态UIGestureRecognizerStateChanged下调用drawLine方法进行,手势结束后存储当前绘制线条的图片

- (void)drawingViewDidPan:(UIPanGestureRecognizer*)sender
{
    CGPoint currentDraggingPosition = [sender locationInView:_drawingView];
    
    if(sender.state == UIGestureRecognizerStateBegan){
        _prevDraggingPosition = currentDraggingPosition;
    }
    
    if(sender.state != UIGestureRecognizerStateEnded){
        [self drawLine:_prevDraggingPosition to:currentDraggingPosition];
    }
    _prevDraggingPosition = currentDraggingPosition;
    
    if (sender.state == UIGestureRecognizerStateEnded) {
        if (self.drawingView.image) {
            [self.revokeImages addObject:self.drawingView.image];
        }
    }
}

三、开启橡皮擦功能

橡皮擦功能其实就是CGContextSetBlendMode,将颜色设置了透明色。

// 橡皮擦
    if(self.erasered){
        CGContextSetBlendMode(context, kCGBlendModeClear);
    }
    

四、撤销功能

撤销功能本质上还是切换图片,将revokeImages存储的图片进行移除操作。

- (void)drawToolDidRevoke {
    if (self.revokeImages.count > 0) {
        [self.revokeImages removeLastObject];
    }
    
    if (self.revokeImages.count > 0) {
        UIImage *image = [self.revokeImages lastObject];
        self.drawingView.image = image;
    } else {
        self.drawingView.image = nil;
    }
}
    

如果取消的话就移除全部图片

- (void)drawToolDidCleanAll {
    self.drawingView.image = nil;
    [self.revokeImages removeAllObjects];
}

    

五、设置涂鸦颜色及width

设置涂鸦颜色就是更改strokeColor,width就是更改画笔宽度

六、小结

iOS开发-图片上涂鸦绘制撤销功能

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1964287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wps在pc端在线预览,而不是下载

如果有有java后端代码如下 SneakyThrowsApiOperation("访问文件")GetMapping("/download/{name}")public void getImage(HttpServletResponse response, PathVariable("name") String name) {String imagePath uploadFilePath File.separator …

文件上传漏洞--之upload-labs靶场第 11-15关(后三关需要制作图片马)持续更新ing...

第11关 第一步:查看源码 这是一个白名单,里面限制了只可以提供它所规定文件jpg,png,gif。 这段 PHP 代码主要实现了文件上传的功能,并进行了一些条件判断和处理: 首先,定义了两个变量 $is_upload 并初始…

GitHub Pages上用vue搭建个人网站简记

新建仓库 将仓库取名为:<你的用户名>.github.io 就像这样 GitHub会帮你自动部署在 https://jerryqjr.github.io/ 上 npm run build后把disk传入新的分支 git subtree push --prefix dist origin gh-pages将子目录 dist 的内容推送到远程分支 gh-pages 随后在 Settin…

综合点评!史上最强开源大模型Llama 3.1

在人工智能领域&#xff0c;开源模型一直是推动技术进步和创新的重要力量。 北美时间7月23日&#xff0c;Meta公司&#xff08;原Facebook&#xff09;宣布了一项重大突破&#xff1a;开源模型Llama 3.1的正式发布。这一举措预示着AI技术的又一次飞跃&#xff0c;Llama 3.1有望…

java~反射

反射 使用的前提条件&#xff1a;必须先得到代表的字节码的Class&#xff0c;Class类用于表示.class文件&#xff08;字节码&#xff09; 原理图 加载完类后&#xff0c;在堆中就产生了一个Class类型的对象&#xff08;一个类只有一个Class对象&#xff09;&#xff0c;这个对…

IOday4

一、思维导图 二、练习 1、使用父子进程完成两个文件的拷贝&#xff0c;父进程拷贝前一半内容&#xff0c;子进程拷贝后一半内容&#xff0c;子进程结束后退出&#xff0c;父进程回收子进程的资源 #include<myhead.h> int main(int argc, const char *argv[]) {//判断终…

分享:Vue3中如何使用echarts工具开发可视化图表

官方链接 点此进入 导入 import * as echarts from echarts 页面 <div id vdrBarChart style"height: 300px;width: 500px;"></div> 调用 //DOM 更新完成后&#xff0c;延时100ms执行setBarChart方法this.$nextTick(() > {setTimeout(() >…

电路设计-基础2-电阻电容

电路设计-基础2-电阻电容 分立元件常见的分立元件及其功能分立元件的特点 电阻**注意**电阻种类1. 直插电阻&#xff08;色环电阻&#xff09;2. 贴片电阻&#xff08;SMD电阻&#xff09;3. 电位器&#xff08;可变电阻器,滑动变阻器&#xff09;4. 热敏电阻&#xff08;NTC/P…

如何解决部分设备分辨率不适配

1&#xff09;如何解决部分设备分辨率不适配 2&#xff09;Unity中如何实现草的LOD 3&#xff09;使用了Play Asset Delivery提交版本被Google报错 4&#xff09;如何计算弧线弹道的落地位置 这是第396篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&#xff0c;…

运筹说 第120期 | 确定型存储模型

上一期我们一起学习了存储问题及其基本概念&#xff0c;本期小编将带大家学习确定型存储模型的相关内容。 下面我们一起来学习确定型存储模型的五个基础模型吧&#xff01; 模型一&#xff1a;不允许缺货&#xff0c;补充时间极短 为了便于描述和分析&#xff0c;对模型作如下…

基于视觉的语义匹配见多了,那基于雷达的呢?

论文题目&#xff1a; LiDAR-based HD Map Localization using Semantic Generalized ICP with Road Marking Detection 论文作者&#xff1a; Yansong Gong, Xinglian Zhang, Jingyi Feng, Xiao He and Dan Zhang 作者单位&#xff1a;北京驭势科技有限公司 导读&#xff…

【C++哈希应用】模拟实现STL中的unordered_map和unordered_set

目录 &#x1f680; 前言一&#xff1a; &#x1f525; 哈希表的改造1.1 模板参数列表的改造1.2 增加迭代器操作 二&#xff1a; &#x1f525; 封装unordered_map和unordered_set 2.1 unordered_map的模拟实现&#xff1a;2.1.1 unordered_map的测试 2.2 unordered_set的模拟实…

图像自定义画框box标注,坐标像素点获取;通过坐标点画框

1、jupyter-bbox-widget画框&#xff0c;这只能jupyter环境插件使用 pip install jupyter_bbox_widget ##安装 ##注册 jupyter nbextension enable --py --sys-prefix jupyter_bbox_widget使用 from jupyter_bbox_widget import BBoxWidget widget BBoxWidget(imagefruit.jp…

【深度学习】kaggle使用

https://blog.csdn.net/2301_78630677/article/details/133834096 https://blog.csdn.net/xiaojia1001/article/details/139467176 https://www.kaggle.com/ 使用要挂代理&#xff0c;要不然可能无法注册 绑定手机号之后才能使用GPU 每周30h免费GPU使用时长 上传数据集 Ad…

【文件解析漏洞】

使用windows2003sever服务器 第一个&#xff1a;目录解析 1、打开网站目录&#xff0c;右键打开资源管理器 新建一个1.asp文件 在1.asp目录下新建一个2.txt&#xff0c;输入asp的语句 2、使用本机访问windows2003的IP地址 访问http://192.168.189.155/1.asp/2.txt即可 第…

Minio多主机分布式 docker-compose 集群部署

参考 docker-compose搭建多主机分布式minio - 会bk的鱼 - 博客园 (cnblogs.com) 【运维】docker-compose安装minio集群-CSDN博客 Minio 是个基于 Golang 编写的开源对象存储套件&#xff0c;虽然轻量&#xff0c;却拥有着不错的性能 中文地址&#xff1a;MinIO | 用于AI的S3 …

CDP问卷调查

在数字化时代&#xff0c;CDP&#xff08;Customer Data Platform&#xff0c;客户数据平台&#xff09;作为连接企业与客户数据的关键桥梁&#xff0c;正逐渐成为企业营销策略中不可或缺的一环。为了更深入地理解CDP在企业中的应用现状、挑战与未来趋势&#xff0c;我们精心设…

A股探底强势反攻,量价齐声太漂亮

今天的A股探底回升&#xff0c;太阳线反攻&#xff0c;太漂亮了&#xff01;具体原因是这样的&#xff0c;盘面上出现2个重要变化&#xff0c;一起来看看&#xff1a; 1、今天两市低开高走&#xff0c;证券、人形机器人等板块掀起涨停潮&#xff0c;究竟是昙花一现还是有望迎来…

VMware虚拟机安装及虚拟机下安装ubuntu(附安装包)

VMware虚拟机安装及虚拟机下安装ubuntu 0 前期准备1 VMware安装2 VMware虚拟机下安装ubuntu2.1 配置虚拟机2.2 安装虚拟机ubuntu 3 在虚拟机中卸载Ubuntu参考 0 前期准备 1、VMware Wworkstation Pro安装包下载 官网-添加链接描述 百度网盘分享&#xff1a; 链接: VMware 提取…

【ThingsBoard初体验】本地编译踩坑记录

前言 这只是我自己的踩坑记录&#xff0c;以尽快启动项目为主&#xff0c;暂时不对编译出现的问题做深入分析。 第一次接触物联网项目&#xff0c;对于文章出现的问题&#xff0c;如果能帮到其他小伙伴&#xff0c;那是我的荣幸。 大佬们有更好的解决办法&#xff0c;也希望能够…