11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Node.jsで複数の画像をWebPに一度に変換する

Posted at

既存の画像(jpgやpng)をディレクトリを分けつつコマンドで一度にWebPに変換するスクリプトを書きました。
WebPについての説明はここでは割愛します。
公式アナウンス

環境

  • MacOS
  • Node.jsのバージョン・・・12.8.1
  • npmのバージョン・・・6.10.2

前提

以下をインストール済みであることを前提としています。

  • Node.js
  • npm(又はyarn)

ディレクトリ構造

├── node-extensions
│   └── sharp.js ← 実行するスクリプトファイル。
├── package.json
├── src
│   └── images
│       ├── original ← 元の画像を入れるディレクトリ。
│       └── webp ← 変換後の画像を入れるディレクトリ。

パッケージのインストール・スクリプトの実行

必要なもの

スクリプトを書く


const sharp = require('sharp');
const fs = require('fs');
const fsPromise = fs.promises;
const glob = require('glob');
const path = require('path');
const mkdirp = require('mkdirp');

const ORIGINAL_IMG_DIR = glob.sync('../src/images/original/*/'); // 変換前の画像のディレクトリ
const IMG_DIR_ARRAY = ORIGINAL_IMG_DIR.map(imgDirPath => imgDirPath.split('/', 5)[4]); // original/以下のディレクトリ
const WEBP_IMG_DIR = '../src/images/webp/'; // WebP変換後のディレクトリ
const WEBP_IMG_DIR_ARRAY = IMG_DIR_ARRAY.map((name) => WEBP_IMG_DIR + name); // WebP変換後の画像を入れるディレクトリ


/**
 * 画像をWebP形式に変換
 * @param {string} imgPath 元画像のフルパス
 * @param {string} outputDir 出力先のディレクトリ
 * @param {string} outputFilePath 出力するファイルパス
 */
const changeWebpImages = (imgPath, outputDir, outputFilePath) => {
  const fileName = outputFilePath.split('/').reverse()[0]; // 拡張子を含む画像ファイル名
  const imgName = fileName.split('.')[0]; // 拡張子を除く画像ファイル名

  sharp(imgPath)
    .webp({
      quality: 75
    })
    .toFile(`${outputDir}${imgName}.webp`, (err) => { // 画像ファイル名.webpで出力
      if ( err ) console.error(err);
      return;
    });
};


/**
 * 変換後の画像を格納するディレクトリを生成
 */
async function createWebpDir() {
  WEBP_IMG_DIR_ARRAY.forEach((pathName) => {
    mkdirp.sync(pathName);
  });
}


/**
 * 元画像のファイル情報を読み取ってWebPに変換する関数を実行
 */
async function writeFiles() {
  ORIGINAL_IMG_DIR.forEach((dirName, i) => {
    const resolvedPath = path.resolve(dirName);
    fsPromise.readdir(resolvedPath)
      .then((files) => {
        files.forEach((file) => {
          changeWebpImages(`${resolvedPath}/${file}`, `${path.resolve(WEBP_IMG_DIR_ARRAY[i])}/`, `${path.resolve(WEBP_IMG_DIR_ARRAY[i])}/${file}`);
        });
      })
      .catch((err) => {
        console.log(err.message);
      }); 
  });
}

async function init() {
  await createWebpDir();
  await writeFiles();
}

init();

スクリプトを実行する

node-extensions のディレクトリまで移動して以下のコマンドを実行。

node sharp.js

src/images/original/ の下に hoge/ というディレクトリがある場合。
スクリプト実行後に src/images/webp/hoge/ というディレクトリが生成されて、webpに変換した後の画像が格納されます。

余談

以下のような場合はPCが悲鳴を上げるので、一度に実行する量(ファイル容量・数)をほどほどにすることをお勧め致します。

  • ファイルサイズが大きい(数MB単位)画像が50枚以上ある場合
  • 元画像1枚あたりのファイルサイズが数百KBバイトで、1000枚近く一度に処理する場合
11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?