如何使用 Node.js 和 Canvas 創建並保存圖片
改善 Twitter 卡片的一個故事
我會在 Twitter 上分享我的博客文章,曾經有一段時間,我為每篇博文畫了一張圖片。
我設置了 Hugo,使其使用存儲在帖子文件夾中的 banner.png
或 banner.jpg
圖片作為開放圖形圖片,如下所示:
1 | <meta property="og:image" content="https://flaviocopes.com/axios/banner.png" /> |
如果一篇文章沒有圖片,我會顯示我的頭像代替:
1 | <meta property="og:image" content="https://flaviocopes.com/img/avatar.png" /> |
問題來了:我很久以前就停止製作這些自定義的橫幅圖片了,而且我的大部分博文都沒有橫幅圖片。
它們在 Twitter 上看起來都一樣:
我無法手工製作500個橫幅圖片。自從看到 Indie Hackers 為論壇博客文章生成這些圖片(一個很棒的點子)之後,我就一直在考慮以編程方式生成這些圖片。
因此,在獲得了一個很好的橫幅圖片的靈感後,我決定為我的每一篇博文創建一個自定義橫幅。
該橫幅是一個 PNG 圖片,為了保持文章的重點(”如何使用 Node.js 和 Canvas 創建並保存圖片”),我將省略其中的一些部分。
此外,有很多不同的方法可以實現我做的事情,下面只是其中一種方法。
首先,我們需要哪些 npm 包?
只需要一個!canvas
:
1 | npm install canvas |
這個包為我們提供了一個基於 Node.js 的 Canvas API 實現,我們在瀏覽器中非常熟悉和喜愛。
換句話說,我用來生成圖片的所有內容在瀏覽器中也可以運行。
只是,我們不是從 <canvas>
HTML 元素獲取 Canvas 實例,而是載入庫,從中獲取 createCanvas
函數:
1 | const { createCanvas } = require('canvas') |
然後,我調用此函數,傳遞 canvas 的寬度和高度,我設置為 1200x600:
1 | const width = 1200 |
讓我們用黑色來繪製(隨便提一下滾石樂隊的參考):
1 | context.fillStyle = '#fff' |
現在,我們來添加文本。
首先,我選擇了 Menlo 字體,字體大而粗體。我將其居中對齊,然後設置為白色。
最後,我調用 context.fillText()
在 canvas 上繪製文本:
1 | const text = 'Hello, World!' |
讓我們在文本後面繪製一個藍色框:
1 | const text = 'Hello, World!' |
我們將 textBaseline
屬性設置為 top
,以便更容易定位矩形。然後,我使用 measureText()
檢查文本的長度,並使用與繪製文本時使用的相同坐標將其繪製出來。
請確保在文本之前繪製矩形,因為在 Canvas 中,你按照順序將東西一個接一個地繪製在頂部。
很酷!現在,我希望在底部顯示我的網站 URL:
1 | context.fillStyle = '#fff' |
我還想添加我的徽標。為此,讓我們從 canvas
模塊中導入 loadImage
函數:
1 | const { createCanvas, loadImage } = require('canvas') |
然後,我們調用它,指定在運行腳本的相同文件夾中包含的 logo.png
圖片:
1 | loadImage('./logo.png').then(image => { |
一旦承諾被解決,我們就有了圖片對象,可以使用 drawImage()
將其繪製到 canvas 上:
1 | loadImage('./logo.png').then(image => { |
這就是了!現在,我們可以使用 toBuffer()
方法將圖片保存到 image.png
文件中:
1 | const buffer = canvas.toBuffer('image/png') |
以下是完整的代碼:
1 | const fs = require('fs') |
tags: [“node.js”, “canvas”, “image generation”]