🖼️
特定フォルダ配下にある巨大なJPEG画像を探し出してリサイズするやつを書いた(バッチ+VBS+FFmpeg)
はじめに
とあるフォルダに機械的に画像ファイル(JPEG形式)が生成されるが、あまりにも大きいものは縮小するようにと言われた。
でも人の手では到底無理なので機械化した
標準では画像操作ができるプログラムがないので、FFmpegを別途導入した。
コード
watchdog.bat
一定時間おきにファイル走査・リサイズ処理VBSを起動する
watchdog.bat
@ECHO OFF
set WATCHDOG_VBS=D:\path\to\watchdog.vbs
set INTERVAL=5
ECHO ■自動リサイズ処理バッチファイル■
ECHO.
ECHO %INTERVAL% 秒ごとに自動リサイズ処理を行います
:LOOP
cscript //NoLogo %WATCHDOG_VBS%
timeout /T %INTERVAL% /NOBREAK >nul
GOTO :LOOP
watchdog.vbs
指定されたフォルダ内を走査し、指定ファイルサイズより大きい画像ファイルを縮小する
- フォルダ内のファイル・フォルダを探す
- 画像ファイルっぽく、ファイルサイズが指定値より大きく、かつリサイズ済みらしいファイルが存在しなければ、FFmpegを起動し縮小する
- サブフォルダが存在すれば、再帰的に処理を行う
watchdog.vbs
Option Explicit
Dim objWshShell
Set objWshShell = WScript.CreateObject("WScript.Shell")
Dim objFs, objFolder
Set objFs = createObject("Scripting.FileSystemObject")
Set objFolder = objFs.getFolder("D:\path\to\TargetFolder\")
Dim strFfmpegBin, strResizedPrefix, strResizedSuffix, intSizeThreshold, strFfmpegOptVf, intFfmpegOptQ
strFfmpegBin = "D:\path\to\ffmpeg.exe"
intSizeThreshold = 1 * 1024 * 1024 ' ファイルサイズがこれより大きければリサイズ対象とする(バイト単位)
strResizedPrefix = "" ' リサイズしたファイルに付ける接頭辞
strResizedSuffix = "_resized" ' リサイズしたファイルに付ける接尾辞
strFfmpegOptVf = "scale=800:-1" ' FFmpeg FilterGraph オプション see: https://ffmpeg.org/ffmpeg.html#filter_005foption
intFfmpegOptQ = 2 ' FFmpeg Fixed Quality Scale オプション。JPEGの場合は1~10の値を取り、値が低いほど高画質となる
getSubFolder(objFolder) ' ファイル捜索開始
' --- メイン処理終了
' サブフォルダ再帰処理
Function getSubFolder(folder)
Dim objFile
For Each objFile In folder.files
resizeImage(objFile)
Next
For Each objFile In folder.subFolders
getSubFolder(objFile)
Next
End Function
' 画像縮小処理
Function resizeImage(objFile)
Dim strParentFolder, strFileName, strExt, strFrom, strTo
strParentFolder = objFile.ParentFolder ' 親フォルダ
strExt = objFS.GetExtensionName(objFile.Name) ' 拡張子
strFileName = Left(objFile.Name, Len(objFile.Name) - (Len(strExt) + 1)) ' ファイル名(拡張子抜き)
strFrom = strParentFolder & "\" & strFileName & "." & strExt
strTo = strParentFolder & "\" & strResizedPrefix & strFileName & strResizedSuffix & "." & strExt
' JPEGっぽくなければスキップ
If strExt<>"jpg" AND strExt<>"jpeg" Then
Exit Function
End If
' ファイルサイズが指定サイズ以下であればスキップ
If objFile.Size <= intSizeThreshold Then
Exit Function
End If
' リサイズ後のファイルが存在していそうであればスキップ
If objFS.FileExists(strTo) Then
Exit Function
End If
' FFmpegの実行
Call objWshShell.Run(strFfmpegBin & _
" -i " & strFrom & _
" -vf """ & strFfmpegOptVf & """" & _
" -q " & intFfmpegOptQ & _
" " & strTo, _
0, True)
End Function
バッチファイルで動かしている関係上、処理する端末は点けっぱなしである必要があるのが難点か…
1日おきの処理でもよければ、タスクスケジューラにVBS起動を仕込んでおけばよいかもしれない
結局やっぱいらんわと言われたのでここで供養
Discussion