Squoosh CLIを使って画像圧縮を自動化する

Webに画像を貼り付ける場合、スマホなどで撮影した画像はデータサイズが大きすぎて表示されるまでに時間がかかるため、画像を縮小してデータサイズを減らし表示速度を早くする必要があります。この画像縮小ツールは数多ありますが、圧縮率・GUIの使いやすさの点でSquooshを利用しています。

しかし、ブラウザ上で動作するSquooshは1枚ずつしか変換できない上に、画像を開く度にパラメータがリセットされてしまうため、複数の画像ファイルを一括変換する場合は効率が悪いです。

これを解決する手段としてコマンドライン版Squoosh(Squoosh CLI)を使う方法がありますが、インストールと自動化に難儀したのでメモしておきます。

下記手順はMacOS上で動作確認をしています。Windowsの場合はImageMatickをインストーラを使ってインストールし、さらにgitをインストールしたときに一緒にインストールされるgit-bashから起動すればサンプルプログラムが動作すると思います(未確認)。

Squoosh CLIとImageMagickのインストール(Mac OS 12.5で確認)

node.jsをインストールする

下記サイトよりnode.jsのLTS版のインストーラをダウンロードしてインストールする。
https://nodejs.org/ja/download/

インストール後に ‘node -v’コマンドを実行して、目的のバージョンのnode/npmコマンドが正しく動作することを確認しましょう。node.jsのバージョンが期待したものと違うとsquoosh-cliが正しく動作しない場合があります。

# node -v

v16.16.0

$ npm -v

8.11.0

(*)2022.8.6時点でのLTS版はv16.16.0で、このバージョンで動作することを確認しています。最新版の18.7.0ではsquoosh-cliはコマンド実行中にエラーとなり動作しないことを確認しているため、このバージョンは使用してはいけません。

squoosh-cli のインストール

下記コマンドを実行し、squoosh-cliをインストールする。

$ sudo npm i -g @squoosh/cli

インストールが完了したら、下記コマンドを実行してsquoosh-cliが正しく実行できることを確認すること。

$ squoosh-cli -h

Usage: squoosh-cli [options] <files...>

Options:
  ...

ImageMagickのインストール

下記コマンドを実行してインストールする。

$ brew install imagemagick

ブラウザ上でsquooshで変換する場合は縦画像は縦画像として表示されそれを変換しますが、squoosh-cliで変換するとExifの回転情報は参照しないためか横向きの画像になってしまいます。正しい方向で表示されるようにはImageMagickを使用してExif情報を読み取り、変換前に画像を回転させる必要があります。

これで自動化に必要なソフトはインストール完了です。

変換用スクリプトサンプル

下記はExifのrotation情報を参照して画像を回転させたのち、800×800のサイズに収まるように画像ファイルをjpegファイルへ変換するスクリプトのサンプルです。

#!/bin/zsh

export PATH=$HOME/.nodebrew/current/bin:$PATH
export PATH=/opt/homebrew/bin:/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH
export PATH=/opt/homebrew/Cellar/imagemagick/7.1.0-45/bin:$PATH

for file in "$@"
do
	#Fullパスへ変換
	file_fullpath=`ls $file(:a)`

	#変換ファイル出力先
#	output_directory=$(dirname "$file_fullpath") #出力先を変換元ファイルと同じフォルダにする場合
	output_directory=${HOME}/Downloads #出力先を固定する場合

	#変換ファイルSuffix
	suffix="_resize"

	#変換ファイルサイズ
	max_dimension=800

	filename_extention=$(basename "$file_fullpath")
	filename="${filename_extention%.*}"
	extention="${file##*.}"

	file_rotate="${output_directory}/${filename}_rotate.${extention}"
	file_squoosh="${output_directory}/${filename}_rotate_squoosh.${extention}"
	file_output="${output_directory}/${filename}${suffix}.${extention}"

	orientation=`identify -format "%[EXIF:orientation]" $file_fullpath`
	case $orientation in
		8) rotate=270;;
		3) rotate=180;;
		6) rotate=90;;
		*) rotate=0;;
	esac
	convert $file_fullpath -rotate +$rotate $file_rotate

	width=`identify -format "%[width]" $file_rotate`
	height=`identify -format "%[height]" $file_rotate`
	param_resize="{enable:true,"
	if [ $width -gt $height ]; then
		param_resize+="width"
		if [ $max_dimension -gt $width ]; then
			max_dimension=$width
		fi
	else
		param_resize+="height"
		if [ $max_dimension -gt $height ]; then
			max_dimension=$height
		fi
	fi
	param_resize+=":${max_dimension}}"
	squoosh-cli --mozjpeg '{}' --resize ${param_resize} -s "_squoosh" -d "${output_directory}" "$file_rotate"
	mv $file_squoosh $file_output 
	rm $file_rotate

	/usr/bin/osascript -e 'display notification "'"${filename_extention//\"/\\\"}"'" with title "Squoooshで圧縮しました"'
done

Leave comments