自研iOS手写笔记App的一些故事

1,022 阅读5分钟

注意:这篇是软广为主。

我花了两年时间开发了一款iOS的笔记软件,Noting Pro(下载地址:itms-apps://itunes.apple.com/cn/app/id6458345951)

上线两周,一开始是付费¥15,结果是每天都没人下载,现在改为免费,只可以新建5个笔记,但有内购VIP¥15,现在还是没看到什么好转。。

说说我为什么要做这件事,和为什么做了两年,为什么不用苹果的PencilKit这个库:

  1. 我以前是做教育直播的,里面有个白板功能,就是在PDF,word,powerpoint这些文档上蒙一层透明的图层,用QuartzCore和CoreGraphics里的接口来画曲线(使用内置的贝塞尔曲线接口插值,生成一段相对光滑的曲线),使用内置的贝塞尔接口无法做到压感笔峰,但是如果自己实现贝塞尔曲线的生成,计算好一个个插值点的大小,是可以做到压感笔峰变化,但没那么容易,本质还是画一个个大小不同的圆点,橡皮擦功能就没那么容易实现了。多说一句,GoodNotes和Noteful是使用QuartzCore和CoreGraphics实现的(这两个都是香港那边开发的,我怀疑Noteful是GoodNotes的前员工出来另外做的,因为里面有些bugs是一样的),Goodnotes的橡皮擦比Noteful的好(Goodnotes也许是在特定场景下实现的橡皮擦,比如固定透明度alpha为1.0,因为用QuartzCore和CoreGraphics不好控制alpha混合模式,粒度没有细到像素级别,QuartzCore底层是可以做到像素级别的,但公开的接口不好做这一块),Notabilty的技术也许是同样的?

2.如果你是自己实现贝塞尔曲线插值,是可以使用OpenGL ES或Metal来绘制的,这样橡皮擦的实现就相对简单,但另外又会出现另一个难点:就是Layer的层级问题,OpenGL ES或Metal都是单独一个Layer,这时如果加入插入键盘输入的文本或图像,就必须另起一层QuartzCore的Layer给CoreText或图像用,这就无法做到笔触和文本,图像的层级结构,同时导出成PDF时也无法做到手写笔触高清导出,Goodnotes可以,因为它底层的绘制是QuartzCore

3.我选择了用Metal实现,但没选择同样底层是Metal实现的PencilKit这个库,因为我想把控更多的东西,比如后期加入各种各样的笔刷纹理等。。

4.最后,就这样,我自研的绘制引擎大概就是这样了:底层使用Metal来绘制,自己实现了一个B样条曲线的插值算法(和PenclKit一样选择了3阶B样条曲线,3阶B样条曲线是分段的3阶贝塞尔曲线的进阶,可以做到C2连续的光滑度),如果想深究这一块的童鞋,需要先去了解贝塞尔曲线,以及C1,C2的光滑连续度,再去弄懂B样条,我反正在这块是花了3个月的时间,欢迎大家使用Noting Pro,曲线光滑度这块我感觉是更胜Goodnotes和苹果PencilKit一筹的,但性能方面会差一些(指的是计算插值点时需要占用更多CPU时间)。。

5.一开始的1年半时间,我都花在了Metal的性能和B样条曲线的插值算法上,如果选择这条地狱模式的童鞋也要抱着这样的心态,这块是没有捷径的,而且需要你懂一点微积分的连续思想和线性代数方面的知识,我本人的数学系毕业的,出来17年了,大学学的那套数学快丢光了,但相关的数学思想还在,但期间研究得也非常痛苦。。

6.填充算法方面,我先择了泛洪算法(计算机图形学(第四版)的6.13),我花了一晚搞明白了逻辑,花了几天实现出来。。

7.几何形状识别方面,我选择了openCV,可以识别出手写的直线,贝塞尔曲线,三角形,矩形,多边形,五角星,椭圆,圆等,无法像PencilKit一样识别出心形,箭头,PencilKit使用的是AI,所以我的识别准确率比PencilKit的低,后续就是提高准确率和加入箭头心形的识别,或者其他一些花瓣,三叶草的形状识别。。

8.渐变色的混合方面,我用的是shadertoy里的一个脚本,很简单的,如果你会一点线性代数点乘内积方面的知识,很容易想明白,但这一块是个坑,如果要做到套索后旋转缩放,但渐变色不变,对线性代数还是要有一定的研究。。

9.手写笔触存储方面,我使用的是CoreData,原因是它可以上iCloud,同步到所有的iOS设备,这里面的研究我花了大概两个月,主要是得益于 肘子的Swift记事本 一系列CoreData的博客文章。。

总的来说,最后我就做成了一个这样的东西:

  1. 手写的矢量压感笔峰,缩放后笔划不失真
  2. 支持渐变颜色
  3. 支持上云
  4. 无限的undo,redo
  5. 新建页面,图层,随意调整页面的先后顺序和图层的上下位置
  6. 橡皮擦,橡皮擦也支持压感哦
  7. 套索,可以旋转缩放,平移到任何位置
  8. 手写几何形状识别
  9. 填充闭合区域
  10. 胶带纸(渐变色的一个变化)

除了插入文本和插入图像,摘录PDF这几个也挺重要的功能外(后续有时间会开发),其他几大笔记APP有的功能我都基本有了,比如Noteful独有的图层功能(我也有),Noteful和Notabilit有的胶带功能(我也有),Notabilty的跨页书写(我也有),等等。。

优点有,缺点也有,Metal实现的和QuartzCore实现的,之间是有几道很难跨越的坎,欢迎大家下载我的Noting Pro(itms-apps://itunes.apple.com/cn/app/id6458345951)

最后上一张图,Noting Pro大概长这样:

编辑切换为居中

添加图片注释,不超过 140 字(可选)

自己编码,没有UI设计,我也不会,只是在icons8找了一些图标,自己测试,自己运营,收入几乎为0,草。。