
●Squooshというツールを使うと、JPEG画像を品質を保ちながら圧縮率を高めることができる。これまでこのサイトではSquooshでMozJPEGというエンコーダーを選んで、画像を圧縮してきた。かなりファイルサイズが小さくなるし、標準のJPEGと完全に互換性があるので、使わない手はない。SquooshはGoogleの提供。MozJPEGはMozillaの開発。安心して使える。
●で、Squooshで満足していたのだが、GUIで圧縮後の画質を確認しながら使えるのは便利な反面、いくつもある写真を一枚ずつ圧縮するのは面倒だ。圧縮時の品質はデフォルトの75の決め打ちでかまわないので、複数ファイルを一括でパッと圧縮させたい。どうするのがベストか。こういうときはAIの出番だ。ChatGPTとGeminiの両方に相談すると、いろんな解決策を提案してくれた。MozJPEGだと意外と既存ツールが少なく、自分の求める用途にはぴたりとはまらない。小さな専用アプリを作るという考え方もあるが、なるべく簡便で、なおかつ保守性が高い方法がよいので、最終的に採用したのはWindowsのバッチファイルを使うやり方。ChatGPTにバッチファイルまで書いてもらった。
●事前準備として必要なのは、Windows用のMozJPEGの圧縮&展開用のツールを入手すること。mozjpeg-windowsにビルド済みのバイナリがあるので、mozjpeg-x64.zipをダウンロードして展開しておく。実際に使うのはcjpeg-static.exeとdjpeg-static.exeの2ファイル。それぞれ圧縮と展開のための実行ファイルで、コマンドラインから動作する。ファイル名に「-static」が付いているのは実行に必要なライブラリがファイル内部に組み込まれているという意味で、このファイル単体で動作する。これらを置いた同じフォルダに、たとえば mozjpeg75.cmd といった名前で圧縮用のバッチファイルを置き、そのショートカットをWindowsのSendToフォルダに放り込んでおけば、エクスプローラーで画像ファイルを選択して、右クリックして「送る」から使うことができる(複数選択可)。以下はChatGPTに書いてもらった mozjpeg75.cmd の中身。少々乱暴だが、既存ファイルを上書き保存する仕様になっている。自分の使い方ではそれが便利なので。
@echo off
chcp 65001 >nul
setlocal EnableExtensions EnableDelayedExpansion
set "DIR=%~dp0"
set "CJPEG=%DIR%cjpeg-static.exe"
set "DJPEG=%DIR%djpeg-static.exe"
if not exist "%CJPEG%" (
echo cjpeg-static.exe が見つかりません:
echo %CJPEG%
pause
exit /b 1
)
if not exist "%DJPEG%" (
echo djpeg-static.exe が見つかりません:
echo %DJPEG%
pause
exit /b 1
)
if "%~1"=="" (
echo JPEGファイルを指定してください。
pause
exit /b 1
)
set /a OK=0
set /a ERR=0
:LOOP
if "%~1"=="" goto DONE
set "INPUT=%~1"
set "EXT=%~x1"
if /I not "%EXT%"==".jpg" if /I not "%EXT%"==".jpeg" (
echo スキップ: "%INPUT%"
echo JPEGではありません。
set /a ERR+=1
shift
goto LOOP
)
set "TMPBMP=%TEMP%\mozjpeg_%RANDOM%_%RANDOM%.bmp"
set "TMPJPG=%TEMP%\mozjpeg_%RANDOM%_%RANDOM%.jpg"
echo 処理中: "%INPUT%"
"%DJPEG%" -bmp -outfile "%TMPBMP%" "%INPUT%"
if errorlevel 1 (
echo デコード失敗
set /a ERR+=1
goto CLEANUP
)
"%CJPEG%" -quality 75 -progressive -outfile "%TMPJPG%" "%TMPBMP%"
if errorlevel 1 (
echo エンコード失敗
set /a ERR+=1
goto CLEANUP
)
if not exist "%TMPJPG%" (
echo 出力ファイルが作成されませんでした。
set /a ERR+=1
goto CLEANUP
)
for %%A in ("%TMPJPG%") do set "NEWSIZE=%%~zA"
if "!NEWSIZE!"=="0" (
echo 出力ファイルが空です。
set /a ERR+=1
goto CLEANUP
)
move /Y "%TMPJPG%" "%INPUT%" >nul
if errorlevel 1 (
echo 元ファイルの置換に失敗しました。
set /a ERR+=1
goto CLEANUP
)
echo 完了
set /a OK+=1
:CLEANUP
if exist "%TMPBMP%" del /Q "%TMPBMP%" >nul 2>&1
if exist "%TMPJPG%" del /Q "%TMPJPG%" >nul 2>&1
shift
goto LOOP
:DONE
echo.
echo 完了: !OK! ファイル
if not "!ERR!"=="0" echo エラーまたはスキップ: !ERR! ファイル
if not "!ERR!"=="0" pause
exit /b
●3行くらいのスクリプトで済むかと思いきや、例外処理をていねいに組み込んできたので、長い。djpegで展開した後、いったん懐かしのBMPで画像を吐き出し、これをcjpegで圧縮して、最後にBMPを削除する、という手順になっている。間にBMPを噛ませなくても同じことはできるけど、元ファイルを上書きすることを考えると、このやり方のほうがトラブル時に追跡しやすいとのこと(ChatGPT談)。実際に使ってみたところ、ひとまず問題なく動作している。Squooshを使うより、さらにお手軽。当面、このやり方で試してみよう。上に載せた写真はjpg100で622KBだったものが、MozJPEG 75で88.2KBに圧縮されている。