创客爱自拍: ASCII 字符拍立得

创客爱自拍: ASCII 字符拍立得

在今年的创客盛会“深圳制汇节(Maker Faire Shenzhen)”里,深圳本地的创客组织 SZDIY 以一个“POLASCII 字符拍立得”的展示项目吸引了许多人的注意,一时间字符画的复古风大受欢迎,两天下来拍了一千多张照片,它最大的特色是每个人可以打印一张二维码的小票,只要用手机扫一扫二维码就可以打开一张自己拍的字符照片,还可以分享到微信朋友圈等等。作为这个业余小项目的作者,鄙人来分享它的诞生过程,解开神秘的面纱。:)

字符拍立得项目的初衷,就是我希望能在“深圳制汇节”以 SZDIY 社区的名义做一个展示性的互动作品,一定要让人印象深刻而达到宣传的目的,同时又能够跟参观者互动,让他们能够感受到科技的乐趣。实际上从几个月前就开始构思了,当时无意中看到一个叫“dyne.org”的国外社区里看到有人做了一个可以将摄像头变成实时字符视频的 “HasciiCam ”项目,马上想到这种字符化的风格本身就很 Geek,用在制汇节里非常适合。但要作为创客的项目,当然不能就这么简单地复制别人的作品,一定要加上自己创作的元素。于是我就开始构思,既然摄像头能够作为录影工具,那我不如把它的改成照相机,做成一个即拍即取的拍立得相机,这样参观者可以给自己留影,有照片可以拿走,我们还可以在给他们的照片上打上 SZDIY 的网址,岂不是一举多得?

1. 技术可行性的调研

有了这个灵感之后,接下来就是要思考它的具体形态,以及测试技术上的可行性。初步分析了一下 HasciiCam 的源代码,发现它是用了 Linux 下面一个很多年前就有人写好的 aalib 库,这个库实现了从图像到字符的转换,而且还有多种格式。HasciiCam 使用 C 语言写的,我对 Linux 下的 C 编程并不熟悉,但可以用 Python,于是就顺藤摸瓜找到了有个 python-aalib 的库,它封装了 aalib 这个 C 语言库,于是这说明了我可以用 Python 来实现到这个功能!

于是我便得出来用 Python 来实现整套东西的想法。当时 SZDIY 还有人在玩树莓派(Raspberry Pi),于是我就想直接把这个东西做成个盒子,用树莓派和它的摄像头拍照,接上一个超市里大小票的热敏打印机,拍一张就吐一张照片出来,完成了整个拍立得的过程。这就是我构想的「字符拍立得」最初的形态。

大概在制汇节之前的一个半月左右,我们 SZDIY 在开放制造空间自发组织了一场“HACK42 黑客马拉松”,我也正好借这次机会把整个项目的想法给大家讲讲,同时尝试能不能把原型做出来。于是在筹备的过程中,danfei 给我借了热敏打印机,DD 给我借了树莓派、摄像头和 7 寸显示屏,laowang 答应给我做一个盒子来装这些东西,而我则负责所有的代码实现,希望集合大家的力量把这个想法做成!于是,我花两天的时间把每个流程里要用到的技术都分析清楚:在树莓派上有 picamera库 可以读取摄像头拍照,通过 PIL 图形处理库转换成黑白照片,然后用 python-aalib 把照片转换成字符画,在屏幕终端上输出文本,再用 python-escpos 库控制热敏打印机的打印。

实际上,技术调研的过程会有很多意外的,但是每一次失败都会让人学到一些经验。比如说 danfei 带来的热敏打印机,却忘了电源线在哪了,我们随便找了根 12V 的电源线接上,弄了几天都没办法把打印机驱动起来,后来想起来热敏打印机的原理是需要产生高温,需要输出电流较大的电源才可以,于是找到了电流大的电源才解决问题。还有在树莓派上把摄像头转字符部分做好之后,发现刷新率很低,差不多一秒才能更新一帧,这对体验有很大的影响,于是想了几种办法来优化却只能把时间缩减一半,仍然不能让人满意。最后通过定位原因发现,是照片转字符的过程无法优化,应该是由于树莓派本身的浮点运算能力较低所致,虽然最后决定换成在 PC 平台上做,不过这个过程却让我了解到每个步骤的技术细节。

2. 尽一切可能克服困难

很多时候最初的想法都会撞到现实的墙壁,这些不理想的结果会逼着你用更现实的方法让想法落地,甚至扭转劣势为优势。从树莓派换到 PC 平台只是其中的一个小挫败,但很快就发现这是个好的选择——由于我是用 python 进行开发的,程序里的大部分代码都可以在这两个平台上运行!唯一要改变的只有读取摄像头的库,因为树莓派的库 Picamera 是专用的,转到 PC 的 Linux 平台之后,我要切换成用 OpenCV 来读取。这个切换花了一点时间,因为 OpenCV 本身是一个功能强大且复杂的库,而且它的 Python 库的文档不是很易读,从零开始入手的话要求我必须快速找到关键信息解决这个摄像头的小问题,经过几个晚上的努力之后终于能够把它调通。

调试完拍照和转换成字符的功能后,才开始着手写打印字符照片,这是发现了一个更严重的问题——热敏打印机上的纸只有 57mm,384 个点,32 个字符的宽度,当照片转换成 32 个字符宽的时候,这基本上很难认出来是什么东西,这个意外可能会让我整个拍立得的想法都无法实现!于是我思考了几种调整的方案:1. 把照片横着来打,这样就变成照片高度是 32 字符,宽度则可以不受限制;2. 直接用打印机的图片打印功能;3. 把照片分成几个小块,打出来之后再拼起来。

但是很快这三种方案都否定了:1. 由于照片的宽高比例,字符照片还是太小,认不出来是什么;2. 热敏打印机的图片打印功能虽然可以用,但是它的原理跟打印字符是不一样的,要把图像数据传过去并打印一张照片的过程耗时很长,无法高效打印;3. 分成小块之后要打的内容很多,而且组装过程会比较复杂,也难以使用。于是结论就是——我得另外再想让用户拿到照片的方法!

虽然用打印机打印能保证画面够大照片清晰,但是当你把一台打印机搬过去参展现场,就这么简单用普通的简单功能那就显得太没趣了。因此,我还是非常希望继续用小票机做些什么,比如说,它还能打印二维码!这样只要我能用网站保存照片,用户就可以通过二维码链接访问到他们的照片,这样二维码小票也就间接地成为了他们手上拿到的照片。而且,我想起来 aalib 里面是支持 HTML 格式导出的,而且图片还会带四级灰度色彩,比普通的字符又更有表现力,这就是又一个劣势转换成优势的例子!

然而下一个问题接踵而来,我发现别人写的那个 python-aalib 的库竟然没有封装到 aalib 导出 HTML 的这个功能!这意味着我必须在他的源码基础上再增加接口,这回我就不得不把 aalib 的 C 库、python-aalib 的源代码研究了一番,顺便还学习了 Python 的 Ctypes 用法,自己来完成接口封装这一层。最后的最后,我还要再写一个服务器的接口,让客户端可以上传 HTML 并生成显示链接。到此为止,我已经从输入端(摄像头)、输出端(热敏打印机)、客户端、服务器端走了一圈,在这一个月时间里饥渴地阅读着资料和不断试验,才把所需的全部技术打通,顺便把项目展示的网站 (http://polascii.szdiy.org/) 都搭起来了。

3. 使用体验的调整

在所有技术都准备好以后,剩下的时间就是为展出做好准备了。为了要在 Maker Faire 上面顺利展出,各种可能影响使用体验的各种细节都要考虑清楚,否则稍微一点意外就有可能是 Showstopper。在整套方案搭好之后,借 SZDIY 每周四聚会的时间,我也让大家试用了几次,看看他们遇到什么样的问题,以及有什么改进建议。

原本考虑用树莓派的 7 寸屏做展示的计划,后来就被 laowang 改成直接用液晶显示器搭一个架子,在架子顶上外接一个摄像头,跟人身高差不多,拍照时就很方便;打印的小票上,除了二维码以外,还放上了缩略图,后来加上了网址以防二维码扫不出来;提前调查场地的 WIFI 热点以确保照片能有网络上传,而且加上了超时及重传的机制,以防网络不稳定的时候影响打印票据,在网络稳定的时候自动把没上传成功的照片重新上传一次,等等。

虽然这个作品最终在展出的时候看起来像是一个半成品一样,如果以产品的眼光来看的话,它实在算不上漂亮,但作为一个原型级别的作品来说,它展示出来的体验还是很流畅的:能够实时地取景拍摄,稍等片刻就可以拿到一张小票,在你拿出手机扫二维码的瞬间,它已经把照片上传到服务器上,马上就可以查看了。如果速度上做不到这么流畅,一天下来花在等待的时间上就有很多,那么能拍到的照片数就要大大减少,不但影响了参观者的印象,也使宣传效果大减,这跟产品设计的过程是相似的,想想在这些细节上的细致考虑,最后都是有价值的。

在做这个作品之前,这些技术我以前都从未尝试过,通过这样一个制作过程学到了非常多东西,这也是我所理解的创客的乐趣。我所喜欢做的事情就是做一些有趣的东西,能够让人留下印象,同时自己又得到知识和经验,即使是花费了许多业余的时间,也会觉得很开心。而且这个项目得到了不少朋友的帮助,设备什么的都是其他人提供的,最后把这个项目做成,大家也分享到这份喜悦。这也是为什么我会以开源的形式把相关的资料都放到网上,因为「从社区来的得到收获,也要分享回馈给社区」。其实这个过程并没有多神秘,只要你不给自己的知识设限,只要你愿意探索愿意动手尝试,在 SZDIY 这样的社区里就会成长得很快。只要有好奇心,任何人都可以成为创客。

最后让我们欣赏几张字符立拍得的好玩照片吧。

创客
关注极客公园公众号
反馈