一次canvas中文字转化成图片后清晰度丢失的探索

本文最初记录在 2017 年 D2 期间。知乎问题为:参加第12届D2前端技术论坛,你有什么收获?
主要是想说一下百度的小姐姐分享的话题 《打造前端复杂应》。

最近正好接手了这样一个类似的项目,(百度 h5 百度脑图)不过整体全是基于 canvas 的,而且也没有事件广播,没有数据驱动,没有模型,全是直接 jquery 直接操作 DOM 的。整体感觉很混乱。现在一个人维护,改起来,感觉很忧伤。

不过听完分享之后,不管是事件广播,还是直接数据的双向绑定,都让我多了很多思路去改造。目前第一步就是先加入了 webpack、ES6、React、PubSub ,先把之前的 jquery 逐渐干掉吧。


不过小姐姐提到百度脑图 和 百度 H5 分别使用 SVG 以及 原生 DOM 来实现的,这样当然没什么问题,不过也提到为什么没用 canvas 的原因,主要是 事件绑定,元素选择相关的等等一些方面的考虑。

但是实际上,根据我项目的使用来说,直接使用 canvas 也是可以的,基本能解决掉提出来的顾虑,当然主要是有这个强大的开源 canvas 操作库:

fabric.js: Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

事件,动画,选中,变换,loadJOSN(),toJSON() 。强大之处,不太好用几句话说清楚,部分功能如下图,建议官网体验:


上面一堆都是废话。

下面是想要说的一个问题,本来想在现场提出来的,但是没被点名到。不过有一个小哥提到了百度 H5 在导出图片的清晰度的问题,说截图都比导出的图片清晰,然后每次做完都只能手动截图。。
我遇到的也类似。不过,经过排除主要聚焦在字体。(其实我觉得那个小哥,也应该是图片中的字体不够清晰)

在将 dom / canvas 生成图片时,都会发现其中的文本在不同系统平台下有着非常大的清晰度差异(和所选的字体也有一定相关)。(说到字体,就会谈到中文字体的子集化,和 WebFont 动态生成这个也很有意思。推荐一个开源库font-carrier:很久没更新了,依赖被写死,需慎重。 这里不谈)

下图有四种图片生成方式: 本地 qq 截图;psd 导出; mac phantomjs 网页截图 ; CentOS phantomjs 网页截图。(未按顺序,清晰度各有不同,最底部是一行是图片),查看大图。。

相信可以很清楚的看出来其中存在的巨大差异。。。

。。。。在排除 phantomjs 配置问题,已经字体是否生效的问题。。(也试了在 window 下使用 phantomjs 网页截图 效果更差。)

最后在我这里给出的结论就是生成图片的清晰度主要受两方面影响(其实浏览器也一样?):

1. 不同的操作系统底层对于字体的渲染原理和方式差异。
2. 字体原本选用的字体生成类型 TrueType / OpenType 等特性差异

然后问题暂时在我这到此为止了。以上两个问题,我目前的能力都还解决不了。。。
欢迎打脸。。。也欢迎有类似问题的一起聊聊


2018-03-05 记录 上面清晰度的问题已经解决。

  1. 同时购入 mac serverwindows server 用于图片生成。 ( mac 的文字显示效果与 mac 电脑的一致。(相对于 windows 来说 加黑加粗了
  2. 弃用了 phantomjs 改用 google 出品的 Puppeteer。
  3. 截图选项使用 png (即使是 quality 100 的 jpg 仍旧渲染会有问题。如果 png 文件过大, 再使用 imagemagick / GraphicsMagick 进行压缩。
使用搜索:谷歌必应百度