用IMGKit生成图片

微信小程序的呼声虽然越来越高,但是自身的限制还是非常严格,让最多人头疼的就是,无法将小程序分享到朋友圈。但是也不能眼睁睁地看着朋友圈的流量入口不用,所以很多人用了迂回的方法。既然小程序无法分享,生成图片再分享总可以了吧。

所以,现在多数小程序中分享到朋友圈的实现方法,都是生成截图(截图中带上小程序的二维码),保存到用户的手机,然后再引导用户把图片分享到朋友圈。虽然是麻烦,但也算是折中办法了。

分享图片,总不能让用户手机截图吧,所以必须要让系统可以自动生成排版好看的图片,用户点击分享的时候,实际上是把生成好的图片下载下来。

例如 @Fenng 团队做的小程序 Readhub,分享到朋友圈的效果是这样的:

readhub_jietu

那么问题来了,如果是在 Rails 项目,如何生成这样的图片呢?答案是是用 IMGKit 这个 gem。IMGKit 可以把一个 HTML 页面导出保存成图片。IMGKit 配合着 CarrterWave(点击看官方示例),实现思路就很清楚了。

第1步,把要生成的图片用 HTML 写出来,包括 CSS 的样式(可以新建一个临时网页来用于调试);

第2步,用 IMGKit 生成图片,并用 CarrierWave 上传到储存空间里去;

第3步,用 sidekiq 建一个 worker,让生成图片的过程变成异步(尤其是图片素材笔记多的时候,生成图片往往要占比较多的资源,最好用异步实现)

我自己的实践的时候,踩了几个坑:

在第1步的时候,有些 CSS 样式是不支持的。比如我在调试的时候用了 flex,网页效果好好的,但转成图片就全乱了。后来改成用 inline-block 这些样式替代,就可以了;

在第2步的时候,IMGKit 的运作机制是要先在服务器本地建立一个临时文件,保存到 CarrierWave 之后再 unlink 掉,考虑到并发的问题,给临时文件起名的时候一定要带上一个唯一标识,例如 id 就可以;

要在生成的图片嵌套一张图片,例如二维码,这个图片的地址必须是在公网地址,也就是项目内的图片用 image_tag 是 load 不出来的,必须先找个图床;

最大的坑是字体问题。在本地测试,一切完美,但是一部署到服务器上就 GG 了,中文字体完全显示不出来,效果就像这样的:

C2D9A7A9-C397-410A-B7E0-6B26A0C7A75B

Google 之后,查明原因是字体惹的祸。我在 CSS 文件里指定 font-familySource Han Sans 的中文字体,本地的 Mac 自带了这个字体,显示没有问题,但是阿里云的服务器上没有自带中文字体,所以所有的中文都没影了。

我的解决办法:

  1. 下载 Source Han Sans 的简体字体,解压缩后是 .otf 格式;

  2. scp 命令将字体上传到服务器的 /usr/share/fonts/opentype/scp 目录下例如

    scp -r ~/Downloads/SourceHanSans root@xxx.xxx.xxx.xxx:/usr/share/fonts/opentype/scp

  3. 在服务器用管理员身份执行 fc-cache -f -v

最后的效果是这样的

2511509929468_.pic_hd

欢迎用微信扫码体验。

· rails, 小程序, tech