Noob Front End Engineer Blog

CONTACT

nodeで画像の一括リサイズを行う

2021/01/08

概要

Web制作等で「大量の画像のサイズを統一しなければならない」という状況になり、
Photoshopやillustratorで1枚1枚手動でリサイズするという苦行を行った事、
見た事は無いですか?

今回はそういった方達を救済する為、node.jssharpを用いて
画像のリサイズを行うモジュールの作成方法を紹介します🙂

完成品はこちらです。
使用方法はREADME.mdに記載してありますので、お急ぎの方は上記を使用してみてください。

Github強化中なので、☆, フォローいただけると喜びます

環境構築

今回使用するnode_module達は下記の通りです。

module description
fs ファイル、ディレクトリの操作を行ってくれる
sharp 画像サイズの操作を行ってくれる

まずは、今回のデモを行う為のディレクトリを作成・移動、
必要なモジュールをインストールしていきましょう。

bash
# ディレクトリ作成
mkdir demo

# ディレクトリ移動
cd demo

# npm 初期設定
npm init

# モジュールインストール
npm install fs sharp -D

今回のデモは下記のようなディレクトリ構造で行っていきます。

demo
  └ dist
     └ img   # <-- リサイズ後の画像の出力先
  └ src
     └ img   # <-- リサイズ前の画像の格納場所

コマンドでもエクスプローラーでも構わないので、
dist/img/ディレクトリとsrc/img/ディレクトリを作成しておいてください。

リサイズモジュールの作成

package.jsonと同じ階層に、設定用のJSファイルを作成してください。
このファイル名は特に指定はありませんが、今回はsharp.jsという名前で行っていきます。

まずはモジュールの読み込み、
リサイズ対象の画像が設置されているディレクトリを取得してみましょう。

sharp.js
const fs = require('fs');
const sharp = require('sharp');

const files = fs.readdirSync('./src/img', { withFileTypes: false });

fsモジュールのreaddirSyncを使用する事によって、
第一引数内にあるファイルのパス群を取得することができます。
これについては下記の記事がわかりやすかったので参考にさせて頂きました。
Node.jsで高速にファイル一覧を取得するfs.readdirのwithFileTypesオプション

これでfilesにリサイズ対象のファイルパスが格納されました。

横幅を指定して縦横比を保ったままリサイズ

ここからはsharpモジュールを使用して実際にリサイズを行っていきます。
まずは「横幅を指定して縦横比を保ったままリサイズ」をする為のコードを書いていきましょう!

先ほど作成したsharp.jsに下記を追記してください。

sharp.js
if (process.argv[2] == 'w') {
  files.map(file => {
    sharp(`./src/img/${file}`)
      .resize(Number(process.argv[3]))
      .toFile(`./dist/img/${file}`, (err, info) =>{
        if (err) {
          throw err;
        }
        console.log(info);
      })
  });
} 

上記で使用しているprocess.argv[2]というのは、
このsharp.jsを実行する際に渡す『第一引数』の値が入ります。 ここでは第一引数にwを指定した場合、横幅を指定して縦横比固定リサイズを行う処理に入るように作成していきます。

まず、先ほどfsモジュールで取得してきたリサイズ対象のファイルパス群を
ループで回して、全ファイルに対して処理が実行されるようにします。

sharpの第一引数で対象のファイル名、.resize()でリサイズ後のサイズを指定
toFileで出力先を指定しています。

.resize()は第一引数にwidth、第二引数にheightの値が入ります。
今回の場合はwidthsharp.jsを実行する際の『第二引数』の値が入ります。

『argv[2]』 に『第一引数』が入るというのは、よく間違うので注意です!
たまに使うと僕はよく間違えます

では実際に実行してみましょう!
sharp.jsがあるディレクトリで下記コマンドを実行してください。

bash
node sharp.js w 1200

これを実行するとsrc/img/に設置されている画像が
横幅1200固定でリサイズされてdist/img/に出力されるはずです!

縦幅を指定して縦横比を保ったままリサイズ

次は「縦幅を指定して縦横比を保ったままリサイズ」をする為のコードを書いていきましょう!

先ほど作成したsharp.jsに下記を追記してください。

sharp.js
else if (process.argv[2] == 'h') {
  files.map(file => {
    sharp(`./src/img/${file}`)
      .resize(null, Number(process.argv[3]))
      .toFile(`./dist/img/${file}`, (err, info) => {
        if (err) {
          throw err;
        }
        console.log(info);
      })
  });
} 

先ほど作成した「横幅を指定して縦横比を保ったままリサイズ」の処理と内容は殆ど同じです。

変更点としては.resize()の箇所で、第一引数の横幅指定の箇所にnullを指定し、
第二引数の縦幅指定の箇所に、sharp.js実行時の第二引数を指定しています。

実行する際のコマンドは下記の通りです。

bash
node sharp.js h 500

これを実行するとsrc/img/に設置されている画像が
縦幅500固定でリサイズされてdist/img/に出力されるはずです!

縦横のサイズを指定してトリミング

最後に「縦横のサイズを指定してトリミング」をする為のコードを書いていきましょう!

先ほど作成したsharp.jsに下記を追記してください。

sharp.js
else if (process.argv[2] == 'wh') {
  files.map(file => {
    sharp(`./src/img/${file}`)
      .resize({
        width: Number(process.argv[3]),
        height: Number(process.argv[4])
      })
      .toFile(`./dist/img/${file}`, (err, info) => {
        if (err) {
          throw err;
        }
        console.log(info);
      })
  });
} 

先ほどまでの処理と内容は殆ど同じです。

今回も変更点としては.resize()の箇所で、widthheight
指定することで、そのサイズでトリミングを行う事ができます。

実行する際のコマンドは下記の通りです。

bash
node sharp.js wh 1200 500

これを実行するとsrc/img/に設置されている画像が
横幅1200, 縦幅500でトリミングされた画像がdist/img/に出力されるはずです!

おわり

今回はsharpモジュールの活用法をご紹介しました。

最後に紹介したトリミングは、デフォルトで中央を基準にトリミングしますが、
基準を変更する事もできたり、いろいろとカスタマイズが可能です!

その他にも公式サイトの方でプロパティの説明等行われていたりするので
是非見てみてください!


Written by daichi iwamoto