前陣子公司的產品經理找我談個需求,但願能爲每一個用戶生成專屬的資訊分享圖片及讓開通專欄的用戶可以生成專屬的文章分享圖片。這兩天恰好有空,就抽空預研了 "生成專屬的資訊分享圖片" 這個功能。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服務,但還有一些流程須要優化,有興趣瞭解具體細節或有更好方案的小夥伴能夠給我留言哈。框架