Node.js向け画像編集ライブラリSharp

Node.js向け画像編集ライブラリのSharpの紹介。

特徴

  • npmパッケージのみで完結していて外部ライブラリの依存は無い
  • 入力はJPEG、PNG、WebP、TIFF、GIF、SVGに対応
  • 出力はJPEG、PNG、WebP、TIFFに対応
  • フォーマット変換、拡大・縮小、クロッピングなど各種基本的な機能は網羅
  • インターフェイスはCallback、Promise、Streamに対応
  • ドキュメントによるとImageMagickより4〜5倍早いらしい
  • 名前からお察しの通りググラビリティは壊滅的
  • ライセンスはApache-2.00.22.0現在)

使い方

インストール

yarnかnpmでインストールするだけでOK。
ネイティブモジュールも含まれるのでそこだけ注意しましょう。

$ yarn add sharp

以後のサンプルは0.22.0のものです。

基本的な使い方

説明不要なくらいシンプル。
sharp()にファイルパスを渡すと入力画像をファイルから読み込んでくれるけどBufferを渡すことも可能。
各種処理をメソッドチェーンで指定して最後に出力用の処理を指定するだけ。

const sharp = require('sharp');

(async () => {
  try {
    await sharp('input.jpg')
      .resize(200, 200)
      .png()
      .toFile('output.png');
  } catch (error) {
    console.log(error);
  }
})();

StreamAPIを使う場合は何も指定しないとTransform Streamが返ってくる。
こっちのほうが使う機会多そう。

const sharp = require('sharp');

const resizer = sharp()
  .resize(200, 200)
  .png();

readableStream
  .pipe(resizer)
  .pipe(writableStream);

リサイズ

第一引数が横幅、第二引数が縦幅、第三引数がオブジェクトでオプションを指定。
第一引数と第二引数はオブジェクトでwidthheightを指定した時と同じ。

const resizer = sharp()
  .resize(200, 200);

どちらか一方を指定してリサイズすると指定しなかった方の長さはお任せになる。

// 横幅200pxで縦幅おまかせ
const resizer = sharp()
  .resize({ width: 200 });

// 縦幅200pxで横幅おまかせ
const resizer = sharp()
  .resize({ height: 200 });

fitを指定すると元画像と指定したサイズの縦横比が一致していなかった時のリサイズ方法を指定できる。 デフォルトはcover
カットしたり塗りつぶしたりする場合はデフォルトだと中央寄せだけどpositionで端に寄せたりすることも可能。

const resizer = sharp()
  .resize({
    width: 200,
    height: 200,
    fit: 'cover',      // 短辺に合わせてリサイズしてはみ出た部分をカット
    // fit: 'contain', // 長辺に合わせてリサイズして足りなかった部分を塗りつぶし
    // fit: 'fill',    // 縦横比無視でリサイズ(無視するので歪む)
    // fit: 'inside',  // 長辺に合わせてリサイズして短辺の方のリサイズ設定は無視
    // fit: 'outside', // 短辺に合わせてリサイズして長辺の方のリサイズ指定は無視
  });

元画像のサイズが指定したサイズより小さい場合のときの挙動はwithoutEnlargementで指定できる。
デフォルトはfalseで元画像のほうが小さい場合は指定したサイズにリサイズする。
trueを指定した場合は拡大しないけど拡大しないので指定したサイズを下回る場合があるので注意。

const resizer = sharp()
  .resize({
    width: 200,
    height: 200,
    withoutEnlargement: true,
  });

参考リンク