前阵子公司的产品经理找我谈个需求,但愿能为每一个用户生成专属的资讯分享图片及让开通专栏的用户可以生成专属的文章分享图片。这两天恰好有空,就抽空预研了 "生成专属的资讯分享图片" 这个功能。javascript
进入正题前,咱们先来看一下最终实现的效果图:前端
接下来咱们来简单的介绍一下 "生成专属的资讯分享图片" 这个功能需求:java
了解完这个需求,我脑海中有三个可选方案:python
因为对 App 端(Android 和 iOS)都不熟,只懂了点皮毛,因此打算就直接尝试第二种方案。肯定使用第二种方案,我并无立刻动手开始开发,而是先在网上找一些相关的文章,由于以为这个需求应该挺常见的。果真经过一番检索,找到了用程序生成一张在简书的专属分享图片这篇文章。文章做者对功能作了详细的分析,而后利用 Python 强大的图片处理库 Pillow 进行功能实现。建议有兴趣的同窗,直接阅读原文。ios
虽然 Python 勉强算入门,结合 Pillow 的 API 文档,做者写的代码基本能看懂,但做为一个喜欢折腾的小前端,怎能不使用咱们的 Node.js 来折腾一下呢?说作就作,固然立刻到 npm 上挑选 Node.js 的图片处理库。通过一番筛选,最终选中了 sharp,这是为何?固然是喜欢它的名字咯(嘿嘿,实际上是看中它的高性能)。git
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images. Uses the libvips library. http://sharp.pixelplumbing.com/
再次感谢 用程序生成一张在简书的专属分享图片 该文章的做者,他把项目源码和资源都放到了 Github - jianshu_share 上。由于只是技术预研,我就直接使用该项目的图片资源,接下来咱们来介绍一下具体实现。github
// 建立圆形SVG,用于实现头像裁剪 const roundedCorners = new Buffer( '<svg><circle r="90" cx="90" cy="90"/></svg>' ); /** * 生成圆形的头像 * @param {*} avatarPath 头像路径 */ function genCircleAvatar(avatarPath) { return sharp(avatarPath) .resize(180, 180) .overlayWith(roundedCorners, { cutout: true }) .png() .toBuffer({ resolveWithObject: true }); }
// 组合多个图层:图片+文字图层 return buffers .reduce((input, overlay, index) => { return input.then(result => { console.dir(overlay.info); return sharp(result.data) .overlayWith(overlay.data, overlayOptions[index]) .toBuffer({ resolveWithObject: true }); }); }, backgroudBuffer) .then((data) => { return sharp(data.data).toFile(outFilePath); }).catch(error => { throw new Error('Generate Share Image Failed.'); });
// 加载字体文件 const textToSVG = TextToSVG.loadSync(path.join(__dirname, "./simhei.ttf")); // 设置SVG文本元素相关参数 const attributes = { fill: "white" }; const svgOptions = { x: 0, y: 0, fontSize: 32, anchor: "top", attributes: attributes }; /** * 使用文本生成SVG * @param {*} text * @param {*} options */ function textToSVGFn(text, options = svgOptions) { return textToSVG.getSVG(text, options); }
通过大半天地折腾,终于借助 Node.js 的 sharp 这个图片处理库,基本实现了上述的功能。因为源码过长,我直接放在 Gist 上,有兴趣的小伙伴能够查看 gen-share-image.js 完整源码。npm
本文主要介绍了如何利用 Node.js 的 sharp 图片处理库,生成专属的分享图片。源码中有不少细节须要处理,如动态获取头像、根据参数动态生成文本信息、异常处理及基于 Koa、Egg.js 或 Express 框架,建立对应的 API 服务等。 gen-share-image.js 源码只是介绍了完整的思路和实现方式,实际开发的时候,在根据具体需求进行调整。虽然目前是已经基于 Koa 开发了一个简单API服务,但还有一些流程须要优化,有兴趣了解具体细节或有更好方案的小伙伴能够给我留言哈。框架