如何在 Node.js 中使用 Sharp 處理圖片

作者選擇了科技多元基金作為撰寫捐贈計劃的捐贈對象。

介紹

數字影像處理是利用計算機分析和操縱影像的方法。該過程包括讀取影像、應用方法來改變或增強影像,然後保存處理過的影像。處理處理用戶上傳內容的應用程式處理影像是很常見的。例如,如果你正在編寫一個允許用戶上傳圖像的 Web 應用程序,用戶可能會上傳不必要的大圖像。這可能會對應用程序的加載速度造成負面影響,同時也會浪費你的服務器空間。通過影像處理,你的應用程序可以調整大小並壓縮所有用戶上傳的圖像,這可以顯著改善應用程序的性能並節省你的服務器磁盤空間。

Node.js擁有一個可用於處理圖像的庫生態系統,例如sharpjimpgm module。本文將聚焦於sharp模塊。sharp是一個流行的Node.js圖像處理庫,支援各種圖像文件格式,如JPEGPNGGIFWebPAVIFSVGTIFF

在本教程中,您將使用sharp來讀取圖像並提取其元數據,調整大小,更改圖像格式和壓縮圖像。然後,您將裁剪、灰度化、旋轉和模糊化圖像。最後,您將合成圖像,並在圖像上添加文本。通過本教程的結尾,您將對如何在Node.js中處理圖像有一個良好的理解。

先決條件

要完成本教程,您需要:

步驟 1 — 設置專案目錄並下載圖片

在開始編寫代碼之前,您需要創建包含代碼和本文將使用的圖片的目錄。

打開您的終端並使用 mkdir 命令創建項目的目錄:

  1. mkdir process_images

使用 cd 命令進入新創建的目錄:

  1. cd process_images

使用 npm init 命令創建一個 package.json 文件來跟踪專案的依賴項:

  1. npm init -y

使用 -y 選項告訴 npm 創建默認的 package.json 文件。

接下來,安裝 sharp 作為一個依賴項:

  1. npm install sharp

您將在本教程中使用以下三個圖片:



接下來,使用curl命令下載您項目目錄中的圖像。

使用以下命令下載第一張圖像。這將把圖像下載為sammy.png

  1. curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/sammy.png

接著,使用以下命令下載第二張圖像。這將把圖像下載為underwater.png

  1. curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/underwater.png

最後,使用以下命令下載第三張圖像。這將把圖像下載為sammy-transparent.png

  1. curl -O https://assets.digitalocean.com/how-to-process-images-in-node-js-with-sharp/sammy-transparent.png

項目目錄和相依性已設置完成,您現在可以開始處理圖像了。

步驟 2 — 讀取圖像並輸出元數據

在本節中,您將編寫代碼來讀取圖像並提取其元數據。圖像元數據是嵌入到圖像中的文本,包括有關圖像的信息,例如其類型、寬度和高度。

提取元数据,首先导入 sharp 模块,创建一个 sharp 实例,并将图像路径作为参数传递。之后,您将在实例上链接 metadata() 方法以提取元数据并将其记录到控制台中。

为此,请在您首选的文本编辑器中创建并打开 readImage.js 文件。本教程使用一个名为 nano 的终端文本编辑器:

  1. nano readImage.js

接下来,在文件顶部引入 sharp

process_images/readImage.js
const sharp = require("sharp");

sharp 是一个基于 promise 的图像处理模块。当您创建一个 sharp 实例时,它返回一个 promise。您可以使用 then 方法解决 promise,或者使用 async/await,它具有更清晰的语法。

要使用 async/await 语法,您需要通过在函数开头放置 async 关键字来创建一个异步函数。这将允许您在函数内部使用 await 关键字来解决读取图像时返回的 promise。

在您的 readImage.js 文件中,定义一个异步函数 getMetadata(),用于读取图像、提取其元数据并将其记录到控制台中:

process_images/readImage.js
const sharp = require("sharp");

async function getMetadata() {
  const metadata = await sharp("sammy.png").metadata();
  console.log(metadata);
}

getMetadata() 是一個異步函數,因為你在 function 標籤之前定義了 async 關鍵字。這允許你在函數內部使用 await 語法。 getMetadata() 函數將讀取一個圖像並返回包含其元數據的對象。

在函數體內,通過調用 sharp() 來讀取圖像,它將圖像路徑作為參數,這裡使用的是 sammy.png

除了接受圖像路徑外,sharp() 還可以讀取存儲在 BufferUint8ArrayUint8ClampedArray 中的圖像數據,前提是圖像是 JPEG、PNG、GIF、WebP、AVIF、SVG 或 TIFF 格式。

當你使用 sharp() 讀取圖像時,它將創建一個 sharp 實例。然後,你將鏈接到 sharp 模塊的 metadata() 方法到該實例上。該方法返回一個包含圖像元數據的對象,你將其存儲在 metadata 變量中並使用 console.log() 輸出其內容。

現在,你的程序可以讀取圖像並返回其元數據。但是,如果程序在執行過程中出現錯誤,它將崩潰。為了解決這個問題,你需要在錯誤發生時捕獲它們。

要做到這一點,請將getMetadata()函數中的代碼包裹在try...catch塊中:

process_images/readImage.js
const sharp = require("sharp");

async function getMetadata() {
  try {
    const metadata = await sharp("sammy.png").metadata();
    console.log(metadata);
  } catch (error) {
    console.log(`An error occurred during processing: ${error}`);
  }
}

try塊內,您讀取一張圖像,提取並記錄其元數據。當此過程中發生錯誤時,執行會跳轉到catch部分並記錄錯誤,以防止程序崩潰。

最後,通過添加突出顯示的行調用getMetadata()函數:

process_images/readImage.js

const sharp = require("sharp");

async function getMetadata() {
  try {
    const metadata = await sharp("sammy.png").metadata();
    console.log(metadata);
  } catch (error) {
    console.log(`An error occurred during processing: ${error}`);
  }
}

getMetadata();

現在,保存並退出文件。輸入y以保存您對文件所做的更改,然後按ENTERRETURN鍵確認文件名。

使用node命令運行文件:

  1. node readImage.js

您應該會看到類似於此的輸出:

Output
{ format: 'png', width: 750, height: 483, space: 'srgb', channels: 3, depth: 'uchar', density: 72, isProgressive: false, hasProfile: false, hasAlpha: false }

現在您已經讀取了一張圖像並提取了其元數據,現在您將調整圖像的大小,更改其格式並對其進行壓縮。

第 3 步 — 調整大小、更改圖像格式和壓縮圖像

調整大小是改變圖像尺寸而不刪除任何內容的過程,這會影響圖像文件大小。在此部分中,您將調整圖像大小,更改圖像類型並壓縮圖像。圖像壓縮是在不損失質量的情況下減小圖像文件大小的過程。

首先,您將從 sharp 實例鏈接 resize() 方法來調整圖像的大小,並將其保存在項目目錄中。其次,您將鏈接 format() 方法到調整大小的圖像上,將其格式從 png 改為 jpeg。此外,您將向 format() 方法傳遞一個選項來壓縮圖像並將其保存到目錄中。

在文本編輯器中創建並打開 resizeImage.js 文件:

  1. nano resizeImage.js

將以下代碼添加到調整圖像大小為 150px 寬和 97px 高:

process_images/resizeImage.js
const sharp = require("sharp");

async function resizeImage() {
  try {
    await sharp("sammy.png")
      .resize({
        width: 150,
        height: 97
      })
      .toFile("sammy-resized.png");
  } catch (error) {
    console.log(error);
  }
}

resizeImage();

resizeImage() 函數將 sharp 模塊的 resize() 方法鏈接到 sharp 實例上。該方法以對象作為參數。在該對象中,您使用 widthheight 屬性設置所需的圖像尺寸。將 width 設置為 150,將 height 設置為 97 將使圖像寬度為 150px,高度為 97px

調整圖像大小後,鏈接 sharp 模塊的 toFile() 方法,該方法以圖像路徑作為參數。將 sammy-resized.png 作為參數傳遞將在程序的工作目錄中保存該名稱的圖像文件。

現在,保存並退出文件。在終端中運行您的程序:

  1. node resizeImage.js

您將不會得到任何輸出,但您應該在項目目錄中看到一個名為 sammy-resized.png 的新圖像文件。

打開您本地計算機上的圖像。您應該會看到一個寬度為 150px,高度為 97px 的 Sammy 圖像:

現在,您可以調整圖像大小,接下來您將把調整大小的圖像格式從 png 轉換為 jpeg,壓縮圖像,並將其保存在工作目錄中。要做到這一點,您將在 resize() 方法之後鏈接 toFormat() 方法。

添加以下突出顯示的代碼以更改圖像格式為 jpeg 並壓縮它:

process_images/resizeImage.js
const sharp = require("sharp");

async function resizeImage() {
  try {
    await sharp("sammy.png")
      .resize({
        width: 150,
        height: 97
      })
      .toFormat("jpeg", { mozjpeg: true })
      .toFile("sammy-resized-compressed.jpeg");
  } catch (error) {
    console.log(error);
  }
}

resizeImage();

resizeImage() 函數中,您使用 sharp 模塊的 toFormat() 方法來更改圖像格式並壓縮它。 toFormat() 方法的第一個參數是包含您想要將圖像轉換為的圖像格式的字符串。第二個參數是一個可選的對象,其中包含增強並壓縮圖像的輸出選項。

要壓縮圖像,您傳遞一個包含布爾值的 mozjpeg 屬性。當您將其設置為 true 時,sharp 使用 mozjpeg 默認壓縮圖像而不損失質量。該對象還可以接受更多選項;有關更多詳細信息,請參閱 sharp 的 文檔

注意: 對於 toFormat() 方法的第二個參數,每個圖像格式都需要一個帶有不同屬性的對象。例如,mozjpeg 屬性僅接受在 JPEG 圖像上。

然而,其他圖像格式也有類似的選項,如qualitycompressionlossless。請務必參考文檔,以了解對於您正在壓縮的圖像格式可接受的選項類型。

接下來,將不同的文件名傳遞給toFile()方法,以將壓縮後的圖像保存為sammy-resized-compressed.jpeg

現在,保存並退出文件,然後運行以下命令執行您的代碼:

  1. node resizeImage.js

您將不會收到任何輸出,但一個名為sammy-resized-compressed.jpeg的圖像文件將保存在您的項目目錄中。

在本地計算機上打開圖像,您將看到以下圖像:

現在,圖像已經被壓縮,檢查文件大小以確認壓縮是否成功。在終端中,運行du命令檢查sammy.png的文件大小:

  1. du -h sammy.png

-h選項生成可讀的輸出,顯示文件大小以千字節兆字節等方式。

運行該命令後,您應該會看到類似於以下的輸出:

Output
120K sammy.png

輸出顯示原始圖像為120千字節。

接下來,檢查sammy-resized.png的文件大小:

  1. du -h sammy-resized.png

運行該命令後,您將看到以下輸出:

Output
8.0K sammy-resized.png

sammy-resized.png 現在比原本的 120 千字節小了 8 千字節。這顯示調整大小操作影響了文件大小。

現在,檢查 sammy-resized-compressed.jpeg 的文件大小:

  1. du -h sammy-resized-compressed.jpeg

執行命令後,您將看到以下輸出:

Output
4.0K sammy-resized-compressed.jpeg

sammy-resized-compressed.jpeg 現在比 8 千字節小了 4 千字節,節省了 4 千字節,表明壓縮起作用了。

現在您已經調整了圖像大小,更改了格式並對其進行了壓縮,接下來將對圖像進行裁剪並轉換為灰度。

步驟 4 — 裁剪並將圖像轉換為灰度

在此步驟中,您將裁剪圖像並將其轉換為灰度。裁剪是從圖像中刪除不需要的區域的過程。您將使用 extend() 方法來裁剪 sammy.png 圖像。之後,您將將 grayscale() 方法鏈接到裁剪的圖像實例上並將其轉換為灰度。

在您的文本編輯器中創建並打開 cropImage.js

  1. nano cropImage.js

在您的 cropImage.js 文件中,添加以下代碼來裁剪圖像:

process_images/cropImage.js
const sharp = require("sharp");

async function cropImage() {
  try {
    await sharp("sammy.png")
      .extract({ width: 500, height: 330, left: 120, top: 70  })
      .toFile("sammy-cropped.png");
  } catch (error) {
    console.log(error);
  }
}

cropImage();

cropImage() 函數是一個異步函數,用於讀取圖片並返回裁剪後的圖片。在 try 塊中,一個 sharp 實例將讀取圖片。然後,鏍鋒模塊的 extract() 方法鏈接到實例,接受一個具有以下屬性的對象:

  • width: 您想要裁剪的區域的寬度。
  • height: 您想要裁剪的區域的高度。
  • top: 您想要裁剪的區域的垂直位置。
  • left: 您想要裁剪的區域的水平位置。

當您將 width 設置為 500,並將 height 設置為 330 時,想像一下鏍鋒會在您想要裁剪的圖像上創建一個透明框。任何符合框的圖像部分將保留,其餘部分將被切割:

topleft 屬性控制框的位置。 當您將 left 設置為 120 時,框將位於圖像左邊緣的 120px 處,將 top 設置為 70 將框定位到圖像頂部邊緣的 70px 處。

框內符合的圖像區域將被提取並保存為單獨的圖像 sammy-cropped.png

保存並退出文件。在終端中運行該程序:

  1. node cropImage.js

輸出將不會顯示,但圖像 sammy-cropped.png 將保存在您的項目目錄中。

在本機機器上打開圖像。 您應該會看到已經裁剪的圖像:

現在您已經裁剪了圖像,將圖像轉換為灰度。為此,您將將sharp實例鏈接到grayscale方法。添加以下突出顯示的代碼以將圖像轉換為灰度:

process_images/cropImage.js
const sharp = require("sharp");

async function cropImage() {
  try {
    await sharp("sammy.png")
      .extract({ width: 500, height: 330, left: 120, top: 70 })
      .grayscale()
      .toFile("sammy-cropped-grayscale.png");
  } catch (error) {
    console.log(error);
  }
}

cropImage();

cropImage() 函數通過將 sharp 模塊的 grayscale() 方法鏈接到 sharp 實例來將裁剪後的圖像轉換為灰度。然後將圖像保存在項目目錄中,文件名為 sammy-cropped-grayscale.png

CTRL+X 保存並退出文件。

在終端中運行您的代碼:

  1. node cropImage.js

在您的本地計算機上打開 sammy-cropped-grayscale.png。您現在應該看到灰度圖像:

現在您已經裁剪並提取了圖像,您將對其進行旋轉和模糊處理。

步驟 5 — 旋轉和模糊圖像

在此步驟中,您將以 33 度的角度旋轉 sammy.png 圖像。您還將對旋轉後的圖像應用高斯模糊。高斯模糊是使用高斯函數對圖像進行模糊處理的技術,它降低了圖像的噪音水平和細節。

在您的文本編輯器中創建一個名為 rotateImage.js 的文件:

  1. nano rotateImage.js

在你的 rotateImage.js 檔案中,請寫下以下程式碼區塊,建立一個函式來將 sammy.png 旋轉到 33 度的角度:

process_images/rotateImage.js
const sharp = require("sharp");

async function rotateImage() {
  try {
    await sharp("sammy.png")
      .rotate(33, { background: { r: 0, g: 0, b: 0, alpha: 0 } })
      .toFile("sammy-rotated.png");
  } catch (error) {
    console.log(error);
  }
}

rotateImage();

這個 rotateImage() 函式是一個異步函式,它會讀取一張圖片並將其旋轉到 33 度的角度。在函式內部,sharp 模組的 rotate() 方法接受兩個參數。第一個參數是旋轉角度 33 度。預設情況下,sharp 會將旋轉後的圖片背景設為黑色。為了移除黑色背景,你需要將一個物件作為第二個參數傳遞,讓背景變為透明。

這個物件有一個 background 屬性,其中包含一個定義 RGBA 顏色模型的物件。RGBA 代表紅色、綠色、藍色和 alpha。

  • r:控制紅色的強度。它接受一個介於 0255 之間的整數值。 0 表示該顏色未被使用,而 255 則表示紅色達到最高強度。

  • g:控制綠色的強度。它接受一個介於 0255 之間的整數值。 0 表示未使用綠色,而 255 則表示綠色達到最高強度。

  • b:控制藍色的強度。它同樣接受一個介於 0255 之間的整數值。 0 表示未使用藍色,而 255 則表示藍色達到最高強度。

  • alpha:控制由rgb属性定义的颜色的不透明度。00.0使颜色变为透明,11.1使颜色变为不透明。

要使alpha属性起作用,您必须确保定义并设置rgb的值。将rgb值设置为0会创建黑色颜色。要创建透明背景,您必须首先定义一个颜色,然后可以将alpha设置为0以使其透明。

现在,保存并退出文件。在终端中运行您的脚本:

  1. node rotateImage.js

检查项目目录中是否存在sammy-rotated.png。在本地机器上打开它。

您应该看到图像旋转了33度:

接下来,您将对旋转后的图像进行模糊处理。您将通过将blur()方法链接到sharp实例来实现。

输入下面突出显示的代码以模糊图像:

process_images/rotateImage.js
const sharp = require("sharp");

async function rotateImage() {
  try {
    await sharp("sammy.png")
      .rotate(33, { background: { r: 0, g: 0, b: 0, alpha: 0 } })
      .blur(4)
      .toFile("sammy-rotated-blurred.png");
  } catch (error) {
    console.log(error);
  }
}

rotateImage();

rotateImage() 函數現在讀取圖像,將其旋轉,並對圖像應用高斯模糊。它使用 sharp 模塊的 blur() 方法對圖像應用高斯模糊。該方法接受一個包含介於 0.31000 之間的 sigma 值的單個參數。將其設置為 4 將應用一個 sigma 值為 4 的高斯模糊。圖像模糊後,您定義一個保存模糊圖像的路徑。

現在,您的腳本將使用 4 的 sigma 值對旋轉後的圖像進行模糊處理。保存並退出文件,然後在終端中運行腳本:

  1. node rotateImage.js

運行腳本後,打開本地機器上的 sammy-rotated-blurred.png 文件。現在,您應該看到旋轉後的圖像已模糊:

現在您已經旋轉並模糊了一幅圖像,接下來您將對另一幅圖像進行合成。

步驟 6 — 使用 composite() 合成圖像

圖像合成是將兩幅或更多分開的圖片結合起來創建單一圖像的過程。這是為了創建借用不同照片中最好元素的效果。另一個常見的用例是使用標誌為圖像添加水印。

在這一部分,你將把 sammy-transparent.png 覆蓋在 underwater.png 上。這將創造出 Sammy 在海洋深處游泳的幻象。要合成這兩張圖片,你將鏈接 composite() 方法到 sharp 實例。

在你的文本編輯器中創建並打開文件 compositeImage.js

  1. nano compositeImages.js

現在,在 compositeImages.js 文件中添加以下代碼以創建一個合成兩張圖片的函數:

process_images/compositeImages.js
const sharp = require("sharp");

async function compositeImages() {
  try {
    await sharp("underwater.png")
      .composite([
        {
          input: "sammy-transparent.png",
          top: 50,
          left: 50,
        },
      ])
      .toFile("sammy-underwater.png");
  } catch (error) {
    console.log(error);
  }
}

compositeImages()

compositeImages() 函數首先讀取 underwater.png 圖片。接下來,你將鏈接 sharp 模組的 composite() 方法,該方法以一個數組作為參數。該數組包含一個對象,該對象讀取 sammy-transparent.png 圖片。該對象具有以下屬性:

  • input: 接受要在處理後的圖片上合成的圖像的路徑。它還可以接受 BufferUint8ArrayUint8ClampedArray 作為輸入。
  • top: 控制要在其上合成的圖像的垂直位置。將 top 設置為 50 會將 sammy-transparent.png 圖像偏移 50 像素,從 underwater.png 圖像的頂部邊緣。
  • left:控制您想要在另一张图片上合成的图像的水平位置。将 left 设置为 50,将 sammy-transparent.png 偏移 underwater.png 图像的左边缘 50 像素。

composite() 方法需要一张大小相似或更小的图像来处理。

为了可视化 composite() 方法的作用,可以将其想象成创建了一堆图像。将 sammy-transparent.png 图像放置在 underwater.png 图像的顶部:

topleft 值将 sammy-transparent.png 图像相对于 underwater.png 图像进行定位。

保存您的脚本并退出文件。运行您的脚本以创建图像组合:

node compositeImages.js

在本地机器上打开 sammy-underwater.png。现在您应该可以看到 sammy-transparent.png 已合成在 underwater.png 图像上:

您现在已经使用了 composite() 方法合成了图像。在下一步中,您将使用 composite() 方法向图像添加文本。

步骤 7 — 向图像添加文本

在這個步驟中,您將在圖像上寫文本。在撰寫本文時,Sharp還沒有一種原生的方法來向圖像添加文本。要添加文本,首先,您將編寫代碼來使用可縮放向量圖形(SVG)繪製文本。一旦您創建了SVG圖像,您將編寫代碼來使用composite方法將圖像與sammy.png圖像合成。

SVG是一種基於XML的用於在Web上創建向量圖形的標記語言。您可以繪製文本,或形狀,如圓圈,三角形,以及繪製複雜的形狀,如插畫,標誌等等。複雜的形狀是使用圖形工具如Inkscape生成的SVG代碼創建的。SVG形狀可以呈現和縮放到任何大小而不失去質量。

在您的文本編輯器中創建並打開addTextOnImage.js文件。

  1. nano addTextOnImage.js

在您的addTextOnImage.js文件中,添加以下代碼來創建SVG容器:

process_images/addTextOnImage.js
const sharp = require("sharp");

async function addTextOnImage() {
  try {
    const width = 750;
    const height = 483;
    const text = "Sammy the Shark";

    const svgImage = `
    <svg width="${width}" height="${height}">
    </svg>
    `;
  } catch (error) {
    console.log(error);
  }
}

addTextOnImage();

addTextOnImage()函數定義了四個變量:widthheighttextsvgImagewidth保存整數750height保存整數483text保存字符串Sammy the Shark。這是您將使用SVG繪製的文本。

變數 svgImage 持有 svg 元素。 svg 元素有兩個屬性:widthheight,這兩個屬性會內插你之前定義的 widthheight 變數。 svg 元素根據給定的寬度和高度創建一個透明容器。

你給了 svg 元素一個 width750height483 的值,這樣 SVG 圖像的大小將與 sammy.png 相同。這將有助於使文字看起來居中在 sammy.png 圖像上。

接下來,你將繪製文字圖形。添加下面突出顯示的代碼以在 SVG 容器上繪製 Sammy the Shark

process_images/addTextOnImage.js
async function addTextOnImage() {
    ...
    const svg = `
    <svg width="${width}" height="${height}">
    <text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
    </svg>
    `;
  ....
}

SVG text 元素有四個屬性:xytext-anchorclassxy 定義了你在 SVG 容器上繪製文字的位置。 x 屬性將文字水平定位,而 y 屬性將文字垂直定位。

x 設置為 50% 會將文字繪製在 x 軸的中心,將 y 設置為 50% 會將文字定位在 SVG 圖像的 y 軸中心。

text-anchor 用於水平對齊文字。將 text-anchor 設置為 middle 將使文字在你指定的 x 坐標的中心對齊。

class 定義了 text 元素上的類名稱。您將使用該類名稱來應用 CSS 樣式到 text 元素。

${text} 插值了存儲在 text 變量中的字符串 Sammy the Shark。這是將在 SVG 圖像上繪製的文本。

接下來,添加突出顯示的代碼以使用 CSS 為文本添加樣式:

process_images/addTextOnImage.js
    const svg = `
    <svg width="${width}" height="${height}">
      <style>
      .title { fill: #001; font-size: 70px; font-weight: bold;}
      </style>
      <text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
    </svg>
    `;

在這段代碼中,fill 將文本顏色更改為黑色,font-size 更改字體大小,font-weight 更改字體粗細。

到目前為止,您已經編寫了繪製文本 Sammy the Shark 的 SVG 所需的代碼。接下來,您將將 SVG 圖像保存為 png 文件,以便您可以查看 SVG 如何繪製文本。完成後,您將將 SVG 圖像與 sammy.png 合併。

添加突出顯示的代碼以使用 sharp 將 SVG 圖像保存為 png

process_images/addTextOnImage.js
    ....
    const svgImage = `
    <svg width="${width}" height="${height}">
    ...
    </svg>
    `;
    const svgBuffer = Buffer.from(svgImage);
    const image = await sharp(svgBuffer).toFile("svg-image.png");
  } catch (error) {
    console.log(error);
  }
}

addTextOnImage();

Buffer.from() 從 SVG 圖像創建了一個 Buffer 對象。緩衝區是存儲二進制數據的臨時內存空間。

創建緩衝區對象後,使用該緩衝區對象作為輸入創建一個sharp實例。除了圖像路徑外,sharp還接受緩衝區Uint9ArrayUint8ClampedArray作為輸入。

最後,將SVG圖像保存在項目目錄中,文件名為svg-image.png

以下是完整代碼:

process_images/addTextOnImage.js
const sharp = require("sharp");

async function addTextOnImage() {
  try {
    const width = 750;
    const height = 483;
    const text = "Sammy the Shark";

    const svgImage = `
    <svg width="${width}" height="${height}">
      <style>
      .title { fill: #001; font-size: 70px; font-weight: bold;}
      </style>
      <text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
    </svg>
    `;
    const svgBuffer = Buffer.from(svgImage);
    const image = await sharp(svgBuffer).toFile("svg-image.png");
  } catch (error) {
    console.log(error);
  }
}

addTextOnImage()

保存並退出文件,然後使用以下命令運行您的腳本:

node addTextOnImage.js

注意:如果您是使用選項2 — 使用 NodeSource PPA 安裝 Node.js選項3 — 使用 Node 版本管理器安裝 Node.js並且出現錯誤fontconfig error: cannot load default config file: no such file: (null),請安裝fontconfig以生成字體配置文件。

更新您的服務器包索引,然後使用apt install安裝fontconfig

  1. sudo apt update
  2. sudo apt install fontconfig

打开您本地机器上的 svg-image.png。您现在应该看到以透明背景呈现的文本 Sammy the Shark

现在您已经确认SVG代码绘制了文本,您将把文本图形叠加到 sammy.png 上。

将以下突出显示的代码添加到将SVG文本图形叠加到 sammy.png 图像的过程中。

process_images/addTextOnImage.js
const sharp = require("sharp");

async function addTextOnImage() {
  try {
    const width = 750;
    const height = 483;
    const text = "Sammy the Shark";

    const svgImage = `
    <svg width="${width}" height="${height}">
      <style>
      .title { fill: #001; font-size: 70px; font-weight: bold;}
      </style>
      <text x="50%" y="50%" text-anchor="middle" class="title">${text}</text>
    </svg>
    `;
    const svgBuffer = Buffer.from(svgImage);
    const image = await sharp("sammy.png")
      .composite([
        {
          input: svgBuffer,
          top: 0,
          left: 0,
        },
      ])
      .toFile("sammy-text-overlay.png");
  } catch (error) {
    console.log(error);
  }
}

addTextOnImage();

composite() 方法从 svgBuffer 变量中读取SVG图像,并将其定位在离 sammy.png 的顶部 0 像素、左边缘 0 像素的位置。接下来,将叠加后的图像保存为 sammy-text-overlay.png

保存并关闭您的文件,然后使用以下命令运行您的程序:

  1. node addTextOnImage.js

在您本地机器上打开 sammy-text-overlay.png。您应该看到图像上添加了文本:

您现在已经使用了 composite() 方法将SVG创建的文本添加到另一张图像上。

结论

在這篇文章中,您學習了如何在Node.js中使用銳利的方法處理圖像。首先,您創建了一個實例來讀取圖像,並使用metadata()方法提取圖像元數據。然後,您使用resize()方法調整圖像大小。之後,您使用format()方法更改圖像類型並壓縮圖像。接下來,您繼續使用各種sharp方法來裁剪、灰度化、旋轉和模糊圖像。最後,您使用composite()方法來合成圖像並在圖像上添加文本。

要深入了解更多有關其他sharp方法的信息,請訪問sharp文檔。如果您想繼續學習Node.js,請參閱如何在Node.js系列中編碼

Source:
https://www.digitalocean.com/community/tutorials/how-to-process-images-in-node-js-with-sharp