🖼️

特定フォルダ配下にある巨大なJPEG画像を探し出してリサイズするやつを書いた(バッチ+VBS+FFmpeg)

2022/07/19に公開

はじめに

とあるフォルダに機械的に画像ファイル(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

指定されたフォルダ内を走査し、指定ファイルサイズより大きい画像ファイルを縮小する

  1. フォルダ内のファイル・フォルダを探す
  2. 画像ファイルっぽく、ファイルサイズが指定値より大きく、かつリサイズ済みらしいファイルが存在しなければ、FFmpegを起動し縮小する
  3. サブフォルダが存在すれば、再帰的に処理を行う
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