取这个名字有投机取巧的嫌疑,希望能对得起先贤 >_<

这是什么?

MaLiang 是 iOS 平台一个基于 OpenGL ES3 的涂鸦绘图库,使用纯 Swift 实现,支持自定义纹理、压力感应、自动笔触等特性,并且提供了一定的自定义扩展的空间。

这篇文章可以看作是对 Github 上 README 说明的详细扩展和补充说明。

使用

我的理念是尽量制造简单、优雅的东西,虽然有时候要做到这一点其实很难,但是尽量往这方面靠吧。MaLiang 的集成和使用都很简单,我把大量对使用者来说没有什么用也没有必要了解的内部逻辑都隐藏了。当然了,如果你的好奇心很重,可以自己去看源代码。这篇文章也会介绍一些内部实现的思路。

集成

MaLiang 已经推送到了 Cocopods 的官方 repo,所以,你只需要在 Podfile 增加一条 Pod 指令然后 install 就可以在项目中使用了:

pod 'MaLiang'
复制代码

然后在需要使用的地方引入 Mudule。当然,首先需要编译一下,否在会报找不到 Moudle 的错误

import MaLiang
复制代码

几个主要的类

1. Canvas

画布是 MaLiang 最基础的组件,所有的涂鸦都发生在 Canvas 上。Canvas 本质上是一个 UIView,所以你可以使用任何你原来创建 UIView 的方法来创建一个画布,并将它添加到你的界面上。

  • 如果你偏好代码流,那么直接调用 UIView 的通用构造函数 init(frame:) 就可以了。

  • 如果你觉得 IB 流才是正道,只要在 xib 或者 storyboard 中拖一个 UIView 到界面上,然后将类名改成 Canvas 后回车就可以了,Xcode 应该会自动将 Module 设置成 MaLiang

Canvas 设置正确的布局约束,然后你就可以开始涂鸦了,比如写一个像下面这样的东东 :)

嗯,想画成这样,确实还缺少一些东西 :)

Canvas 继承自 MLView(ML是 MaLiang 的缩写,不是那个机器学习的东东),MLView 做了几乎所有与 OpenGL 打交道的事情,虽然它被定义成一个 open 的类,但实际使用中基本是用不到的。不过了解一些原理也无伤大雅么~

OpenGL 涂鸦的核心是纹理(Texture),本质上就是沿着手指轨迹,不断地将纹理叠加到画布上的过程。所以能画出什么样的笔迹,完全取决于使用的纹理,以及它的大小、颜色、尺寸等参数。

MLView 初始化之后会使用自带的图片创建一个默认的纹理,这个纹理就是一个简单的不透明的圆点,所以只能画最简单的线条。如果想要画出上图那样的效果,就需要使用相对复杂一点的纹理了。MaLiang 的示例项目里面提供了好几个设定好的纹理,用他们可以模拟出铅笔、水笔以及毛笔的特效,上面的文字就是使用毛笔特效写出来的。

快照

Canvas 提供了一个简单的快照功能:

open func snapshot() -> UIImage?
复制代码

调用该方法会对画布生成一个当前内容的快照并以 Image 的形式返回,快照的实现逻辑很简单,你也可以自己实现更加复杂的快照逻辑。

2. Brush

直接使用纹理还是比较繁琐的,另外与纹理相关的还有颜色、线条的粗细以及其他一些参数,所以这里提供了一个 Brush 类来处理所有的这些数据。

Brush 的属性在改变后会立刻影响接下来的绘制效果。

  • opacity 透明度

上面提到,涂鸦的本质是把纹理叠加到画笔的过程,所以想要做出深浅不一的笔迹,纹理就需要具有透明度,可以通过opacity 属性来调节。

  • pointSize 笔迹粗细

pointSize 直接影响笔迹的粗细,它是以 iOS 尺寸的标准单位 点(point) 来衡量的,所以这是一个自适应屏幕像素密度的属性。你不需要根据设备类型来计算实际像素,直接指定眼睛可见的大小就可以了。

  • pointStep 点距

同上,由于笔迹是通过叠加纹理实现的,因此除了透明度外,两个纹理之间的距离也会影响到笔迹的深浅。另外如果把点距设定到大于笔迹的尺寸,甚至可以画出类似虚线的效果。点距的单位也是 点(point)

  • forceSensitive 压力敏感度

之所以说 pointSize 是影响笔迹的粗细,而不是直接确定,是因为有压力感应的存在。笔迹的实际尺寸会随着压力的大小在 pointSize 指定的尺寸上下浮动,压力越大,笔迹越粗。forceSensitive 影响笔迹对压力浮动的剧烈程度,建议设置为 0 - 1 之间的某个值。如果设置过大,笔迹随压力的便会会太过剧烈而失真;如果将 forceSensitive 的值设置为 0,则对该画笔关闭压力感应效果,笔迹粗细不会随着压力而变化。

MaLiang 默认使用 iOS 设备的压力感应特性,另外在一些不支持压力感应的设备上使用模拟的压力感应。模拟压感依赖手势移动的速度来判断压力的大小,速度越快压力越小。

  • color 颜色

影响笔迹的颜色,实际画出的颜色会计算进 opacity 的值,不过由于纹理之间会叠加,所以相互效果可以基本抵消。你一般不需要为颜色额外指定透明度的值。

  • texture 纹理

texture 是一个非公开属性,实际使用时只需要使用纹理图的 Image 初始化 Brush 对象就可以了,不需要关心 texture 的具体实现。

实际绘制时的颜色是设定的 color 与纹理的颜色混合之后的结果,所以需要保证纹理图是白色的,才能确保绘制正确的颜色。这个问题可能会在未来改善。

texture 实际上是一个 MLTexture 类型的对象,MLTexture 内部分装了纹理相关的 OpenGL 实现,包括创建纹理、切换画笔时的纹理绑定等。

3. Document

Document 不是实现涂鸦的必备组件,它是为了提供一些更加深入的功能而设计的。Document 维护着持有它的画布的所有笔迹数据,依赖这些数据,可以实现撤销和重做功能。这两个功能 MaLiang 已经默认实现。

通过 Document 持有的数据,你还可以轻松实现保存涂鸦数据到文件的逻辑。反过来也可以将保存的数据重新还原成画布图像,这样可以实现跨设备的数据同步功能。

Document 功能默认是没有启用的,需要手动通过代码开启:

canvas.setupDocument()
复制代码

Document 在运行过程中需要使用一部分硬盘空间来存放临时数据,所以如果设备存储空间不足时,上面的操作会抛出一个异常,为了保证程序的健壮性,建议使用 do-catch 模式来捕获可能的异常情况:

do {try canvas.setupDocument()
} catch {// do somthing when error occurs
}
复制代码

计划实现的一些特性

计划中 MaLiang 还存在一些尚未实现的特性,这些特性会在未来逐渐添加进来,当然,你也帮助我实现,然后给我提交 PR :)

  • [x] 撤销 & 重做,目前已经实现

  • [x] 导出图片,已实现

  • [ ] 绘制文本到画布中的指定位置

  • [ ] 绘制指定的图片到画布中的指定位置

  • [ ] 纹理旋转,旋转纹理可以实现一些更加特殊的笔迹效果

由来

MaLiang 起源于多年前的一个涂鸦项目,当时还是基于 Objective-C 和 OpenGL ES1 实现的,OpenGL ES1 对于抗锯齿的支持不是很好,所以涂鸦的效果不怎么敢恭维。并且当时由于太年轻,整个框架的设计和结构都比较凌乱。虽然最后顺利上架了一段时间,不过由于各种各样的原因,整个项目随当时的公司一起无疾而终了。

去年开始重拾这个项目,打算基于 Swift 和 OpenGL ES3 完全重写,同时将当时处理得不是很好的地方加以改进,另外扩展了一些自己近期想到的东西,最终诞生了这个库。

Why Swift?

使用 Swift 直接和 OpenGL 打交道确实不是一件容易的事情,有人奉劝我使用 OC 或者 C 作为中间层来调用 OpenGL,再用 Swift 封装上层逻辑,确实这样可以以最低的成本实现需要的效果。

不过作为一个业余项目,成本并不是我第一考虑的要素,而且这个库虽然是基于 OpenGL 的,但是真正跟 OpenGL 打交道的,其实也就那几百行代码。为了追求这一点点成本和便利性,牺牲整个项目结构的统一和整洁,在我这是无法接受的。

另外,引入 OC 代码意味着同时引入了 OC 的动态运行时环境,这对 Swift 的执行效率会有一定的影响。虽然作为一个 iOS 的项目,现在必然无法摆脱 OC 的动态运行时环境,我的这点偏执似乎也没有什么意义,不过谁知道以后会怎么样呢 :)

应用

说了半天,这个库有什么用?说实话我也不知道,或许可以用来做签名?不过签名其实用 CoreGraphics 就足够了。或许可以用它来做一个画画的 App 来逗小孩玩,可能我真会这么干。。。

说到底,这主要是对当初懵懂时期经历的一个纪念吧。感兴趣的都可以拿去玩 :)

接下来可能会打算基于这个库开发一款涂鸦的 App。当然了,多年前的那个项目是不会复活了,新的这个 App 会是一个融合了很多我自己想法的全新项目。当然了希望不要半途而废 - -!

神笔马良——基于 OpenGL 的涂鸦框架相关推荐

  1. 基于OpenGL ES 的深度学习框架编写

    基于OpenGL ES的深度学习框架编写 背景与工程定位 背景 项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算 ...

  2. 基于OpenGL的Android系统视频转换功能实现

          第1章OpenGL ES 3D图形编程首先OpenGL.OpenGL的英文全称是OpenGL Graphics Library,中午名称是开发式图形库.OpenGL为程序开发人员定义了一个 ...

  3. 转-基于OpenGL的3D天空仿真

    在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动画中有着广泛的应用.但是,目前对于天空的仿真还存在很多不足,一些模拟方法中存在实现复杂.计算耗时.图像分 ...

  4. 基于OpenGL的3D天空仿真

    From:http://www.c-cnc.com/dz/news/news.asp?id=18622 在进行3D场景渲染时,天空是必不可少的因素.对于3D天空的模拟在视景仿真系统.计算机游戏.三维动 ...

  5. Android涂鸦框架Doodle——仿微信图片编辑(多功能画板)

    前言 很久之前做了一个叫Graffiti的涂鸦项目,放在了github上,得到了不少朋友的反馈,也一直有去维护.限制于个人能力水平,一开始并没有过多考虑框架的问题,导致越到后面,代码越臃肿,添加新功能 ...

  6. 基于OpenGL的地形建模技术的研究与实现

    毕业论文 基于OpenGL的地形建模技术的研究与实现 诚信声明 本人郑重声明:本设计(论文)及其研究工作是本人在指导教师的指导下独立完成的,在完成设计(论文)时所利用的一切资料均已在参考文献中列出. ...

  7. Android仿微信图片编辑——涂鸦框架Doodle(多功能画板)

    前言 很久之前做了一个叫Graffiti的涂鸦项目,放在了github上,得到了不少朋友的反馈,也一直有去维护.限制于个人能力水平,一开始并没有过多考虑框架的问题,导致越到后面,代码越臃肿,添加新功能 ...

  8. 基于OpenGL的三维曲面数据场动态显示 (转)

    基于OpenGL的三维曲面数据场动态显示 2007-08-20 08:53 作者: 白婷 赵军 朱双华等 出处: 计算机与信息技术 责任编辑:方舟 摘 要 在大数据量条件下,实时动态显示三维曲面较困难 ...

  9. 9个基于Java的搜索引擎框架

    9个基于Java的搜索引擎框架 转自:http://blog.csdn.net/xiaomin1991222/article/details/50980573 1.Java 全文搜索引擎框架 Luce ...

最新文章

  1. 怎么安装python3-python3怎么安装
  2. yum 不小心删除后安装
  3. java 单开程序_java生成jar包并且单进程运行的实例
  4. 计算机控制面板图标怎么删除,电脑如何找回消失的“添加或删除程序”图标
  5. python中int用法,Python中int()函数的用法浅析
  6. 接口测试工具--apipost如何取消json参数中转义字符
  7. hibernate的HQL查询部分属性
  8. ASP.NET OAuth 2.0 新手上路
  9. 基于STM32F103——SIM900A发送短信+串口打印
  10. 基于微信的买菜小程序 毕业设计毕业论文 开题报告和效果图(基于微信小程序毕业设计题目选题课题)
  11. 写论文修改word标题的编号1/1.1/1.1.1/1.1.1.1
  12. Ubuntu 数字小键盘不能用解决方法
  13. dhcp服务器在作用,dhcp的作用是什么?dhcp优缺点
  14. 关于windows2008r2下access数据库网站报Microsoft OLE DB Provider for ODBC Drivers 错误 '80004005'
  15. 导航算法A*的简单实现
  16. 周金涛:繁荣的起点并非沸腾的年代,或将在2020年出现首次证券市场大繁荣
  17. Codecademy网学习Python第四天
  18. java system.nanotime_java - System.nanoTime()完全没用吗?
  19. Rocket之消息发送
  20. linux 内核 屏幕 驱动,Linux液晶显示屏驱动设计

热门文章

  1. 阿里菜鸟招聘java和客户端开发
  2. php CI 微信支付扩展 微信扫码支付 jssdk 支付 退款
  3. SAP 委外加工会计分录
  4. 【Python画图 04】标注
  5. iPhone摄像头设备获取
  6. 计算机开机响三声 两短,电脑开机滴滴滴响三声是什么原因 电脑开机滴滴滴响三声原因【图文】...
  7. C语言:输入三个整数,从小到大排序!
  8. 实训总结(图书管理系统java)
  9. 基于Echarts和百度地图的HTML插件
  10. 淘宝商品详情API接口(app、h5端)