sharpライブラリのcreateはchannelsとbackgroundを省略するとエラーになる

sharpライブラリとは

Node.js環境で画像の処理と変換するための強力なライブラリです。

以下はsharpライブラリが提供する主な機能や用途です。

  • 画像のリサイズとクロッピング
  • 画像の合成とオーバーレイ
  • 画像の回転と反転
  • 色空間の変更と色調整
  • 画像形式の変換
  • テキストや形状の追加
  • 画像の情報の取得
  • 画像のフィルタリング(エフェクト)
  • 画像のフィルタリングとエフェクト
  • 画像の品質設定

類似のライブラリにImageMagickやJimpなどがありますが、sharpライブラリはこの2つより処理が早いため、私はsharpライブラリをよく利用します。

使い方はnpmコマンドでインストールしてNode.jsで実行するだけです。

詳しい使い方は以下の過去の記事をご参照ください。

sharpでNode.jsによる画像変換処理を使用する方法

createはchannelsとbackgroundを省略するとエラー

タイトルにも書かれているcreateとはsharpでの画像作成に使用するメソッドです。

例えばcreateメソッドを使用して、300x200の背景色が赤の半透明画像を作成する場合は以下のようなコードになります。

import sharp from 'sharp'

sharp({
  create: {
    width: 300,
    height: 200,
    channels: 4,
    background: {
      r: 255, // 赤
      g: 0, // 緑
      b: 0, // 青
      alpha: 0.5, // 透明度
    },
  },
}).toFile('output.png', (err) => {
  if (err) {
    console.error(err)
  } else {
    console.log('新しい画像を作成しました。')
  }
})

コードにあるchannelsとbackgroundはどちらか、または両方を省略すると以下のようなエラーが表示されます。

Error: Expected valid width, height and channels to create a new input image

createメソッドは画像の統合などの下地の画像を用意するなど、汎用的に使われます。

その際に間違えてchannelsとbackgroundを省略しているケースをたまに見かけますので、注意が必要です。

例えば以下のコードはchannelsとbackgroundがコメントアウトされているため、エラーになります。

import { chromium } from 'playwright'
import sharp from 'sharp'

;(async () => {
  const browser = await chromium.launch()
  const page = await browser.newPage()
  const imgFileGoogle = 'screenshot_google.png'
  const imgFileYahoo = 'screenshot_yahoo.png'

  await page.goto('https://www.google.co.jp/')
  await page.screenshot({ path: imgFileGoogle })
  await page.goto('https://www.yahoo.co.jp/')
  await page.screenshot({ path: imgFileYahoo })

  const imageGoogle = sharp(imgFileGoogle)
  const imageYahoo = sharp(imgFileYahoo)
  const metadataGoogle = await imageGoogle.metadata()
  const mergedImageBuffer = await sharp({
    create: {
      width: metadataGoogle.width * 2,
      height: metadataGoogle.height,
      // channels: 4,
      // background: { r: 0, g: 0, b: 0, alpha: 0 },
    },
  })
    .composite([
      { input: await imageGoogle.toBuffer(), left: 0, top: 0 },
      { input: await imageYahoo.toBuffer(), left: metadataGoogle.width, top: 0 },
    ])
    .png()
    .toBuffer()

  await sharp(mergedImageBuffer).toFile('screenshot_combined.png')
  await browser.close()
})()