2011年1月5日水曜日

【悠々自炊ライフ】自炊始めました!(その2)

さて今回は、自炊用の各スクリプトの解説をおこなっていきたい。長い上に、見づらいので悪しからず。

まず、概要から。
スクリプトは、GIMP 上で実行する Script-Fu スクリプトファイルと、それを呼び出すバッチファイルの2種類を作成する。
Script-Fu の格納場所は”<インストールディレクトリ>\GIMP-2.0\share\gimp\2.0\scripts”

バッチファイルは、適宜、好きな場所に置くこと。

■ Script-Fu スクリプト
では、GIMP 上で実行する Script-Fu スクリプトの解説から
それぞれのスクリプトは、GIMP を起動して、「フィルタ」メニューの「AA-Filters」からも実行できる。ただし、その場合フィルター処理のみで、ファイルの保存などは行われない。

始めに、各フィルタの共通処理を記述したスクリプト。どうやら、定義した関数は、他のスクリプトファイルからでも利用可能なようだ。裏を返せば、他の関数名と重複してはいけないということだね。
ファイル名リンクをクリックすると、ファイルがダウンロードできる。
[ AA-jisui-common.scm ]

;=====================================================================
; 自炊用フィルタ共通処理
;
;=====================================================================

;=====================================================================
;
; フルパス指定のファイル名から、拡張子を除いたファイル名を取得
;
;=====================================================================
(define (AA-jisui-common-strip-base-filename full-path-filename)
    (let*
        (
            ; フルパスからファイル名(拡張子を含む)のみを取得(パス区切り文字で分割して、最後の要素を取得)
            (filename (car (last (strbreakup full-path-filename DIR-SEPARATOR))))

            ; ファイル名から拡張子を除いたものを取得("."で分解して、最後を除く要素を"."で結合)
            (filename-without-ext (unbreakupstr (butlast (strbreakup filename ".")) "."))
        )
        filename-without-ext
    )
) 

カラー用のフィルタ。
切抜きと、ノイズ除去処理を行っている。
[ AA-jisui-color-filter.scm ]
;=====================================================================
; 自炊用フィルタ(カラー用)
; カレントフォルダ内の処理対象ファイル名パターンに一致する画像を開き、
; 画像処理後 Output フォルダへ保存するスクリプト
;
; コマンド入力例
; gimp-2.6 -i -b "(AA-jisui-color-filter-main \"C:\\image\\*.jpg\" \"C:\\image\\Output\" 30)" -b "(gimp-quit 0)"
;
; pattern: 処理対象ファイル名パターン
; outputdir: 出力ディレクトリ
; crop-size: クロップサイズ
;
;=====================================================================
(define (AA-jisui-color-filter-main pattern outputdir crop-size)
    (gimp-message-set-handler CONSOLE)
    (gimp-message "自炊用画像フィルタ(カラー用)処理開始")

    (let*
        ; カレントフォルダ内にあるファイルリスト取得
        ((filelist (cadr (file-glob pattern 1))))

        ; ループ処理
        (while (not (null? filelist))
            (let*
                (
                    ; 変数宣言および値の取得
                    (in-filename (car filelist))
                    (image (car (gimp-file-load RUN-NONINTERACTIVE in-filename in-filename)))
                    (drawable (car (gimp-image-get-active-layer image)))
                    ; フルパスの入力ファイル名から拡張子除いたファイル名を取得
                    (out-filename-without-ext (AA-jisui-common-strip-base-filename in-filename))
                    ; 出力先フルパス文字列(拡張子を除く)を生成
                    (out-filepath-without-ext (string-append outputdir DIR-SEPARATOR out-filename-without-ext))
                )
                (gimp-message (string-append in-filename " ファイルの処理を開始"))

                ; 画像を処理
                (AA-jisui-color-filter image drawable crop-size)

                ; JPEG 形式でファイル保存
                (let*
                    (
                        ; ファイル名生成
                        (out-filename (string-append out-filepath-without-ext ".jpg"))
                    )
                    (file-jpeg-save RUN-NONINTERACTIVE image drawable out-filename out-filename
                        ; quality (0<=/<=1)
                        1
                        ; smoothing (0<=/<=1)
                        0
                        ; optimize (0/1)
                        1
                        ; progressive (0/1)
                        0
                        ; comment
                        ""
                        ; subsmp
                        0
                        ; baseline
                        1
                        ; restart
                        0
                        ; dct
                        0
                    )
                    (gimp-message (string-append out-filename " ファイルを保存"))
                )

                ; イメージの削除
                (gimp-image-delete image)
            )
            (set! filelist (cdr filelist))
        )
    )
)

;============================================
;
; フィルタ処理
;
;============================================
(define (AA-jisui-color-filter image drawable crop-size)
    (gimp-message-set-handler CONSOLE)
    ; 切り抜き処理
    (if (> crop-size 0)
        (begin
            (gimp-message "切り抜き処理開始")
            (let*
                (
                    ; 関数の戻り値は、かならず List 形式になっているので、car が必須
                    (width (car (gimp-image-width image)))
                    (height (car (gimp-image-height image)))
                )
                (gimp-image-crop image
                    (- width (* crop-size 2))
                    (- height (* crop-size 2))
                    crop-size
                    crop-size
                )
            )
        )
    )

    ; ノイズ除去処理
    (gimp-message "ノイズ除去処理開始")
    (plug-in-despeckle RUN-NONINTERACTIVE image drawable
        ; 半径
        2
        ; 中央値
        1
        ; 黒レベル
        1
        ; 白レベル
        255
    )

    ; 再描画
    (gimp-displays-flush)
)

;============================================
;
; スクリプト定義
;
;============================================
(script-fu-register
    ; スクリプト名
    "AA-jisui-color-filter"
    ; メニュー名
    "<Image>/Filters/AA-Filters/jisui-color-filter"
    ; 詳細
    "自炊用フィルタ(カラー用)"
    ; 作成者
    "AbsoluteArea"
    ; コピーライト
    "copyright 2011, AbsoluteArea"
    ; 作成日
    "Jan 1, 2011"
    ; 動作モード指定
    "RGB*"

    SF-IMAGE "Image" 0
    SF-DRAWABLE "Drawable"  0
    SF-VALUE "Crop Size (pixels)" "30"
);end of register


モノトーン用フィルタ
切り抜き、脱色、ノイズ除去、色レベル調整、アンシャープマスク処理を行っている。
[ AA-jisui-monotone-filter.scm ]
;=====================================================================
; 自炊用フィルタ(モノトーン用)
; カレントフォルダ内の処理対象ファイル名パターンに一致する画像を開き、
; 画像処理後 Output フォルダへ保存するスクリプト
;
; コマンド入力例
; gimp-2.6 -i -b "(AA-jisui-monotone-filter-main \"C:\\image\\*.jpg\" \"C:\\image\\Output\" 30 FALSE)" -b "(gimp-quit 0)"
;
; pattern: 処理対象ファイル名パターン
; outputdir: 出力ディレクトリ
; crop-size: クロップサイズ
; unsharp-flag: アンシャープマスクフラグ
;
;=====================================================================
(define (AA-jisui-monotone-filter-main pattern outputdir crop-size unsharp-flag)
    (gimp-message-set-handler CONSOLE)
    (gimp-message "自炊用画像フィルタ(モノトーン用)処理開始")

    (let*
        ; カレントフォルダ内にあるファイルリスト取得
        ((filelist (cadr (file-glob pattern 1))))

        ; ループ処理
        (while (not (null? filelist))
            (let*
                (
                    ; 変数宣言および値の取得
                    (in-filename (car filelist))
                    (image (car (gimp-file-load RUN-NONINTERACTIVE in-filename in-filename)))
                    (drawable (car (gimp-image-get-active-layer image)))
                    ; 入力ファイル名から拡張子除いたものを生成
                    (out-filename-without-ext (AA-jisui-common-strip-base-filename in-filename))
                    ; 出力先フルパス文字列(拡張子を除く)を生成
                    (out-filepath-without-ext (string-append outputdir DIR-SEPARATOR out-filename-without-ext))
                )
                (gimp-message (string-append in-filename " ファイルの処理を開始"))

                ; 画像を処理
                (AA-jisui-monotone-filter image drawable crop-size unsharp-flag)

                ; JPEG 形式でファイル保存
                (let*
                    (
                        ; ファイル名生成
                        (out-filename (string-append out-filepath-without-ext ".jpg"))
                    )
                    (file-jpeg-save RUN-NONINTERACTIVE image drawable out-filename out-filename
                        ; quality (0<=/<=1)
                        1
                        ; smoothing (0<=/<=1)
                        0
                        ; optimize (0/1)
                        1
                        ; progressive (0/1)
                        0
                        ; comment
                        ""
                        ; subsmp
                        0
                        ; baseline
                        1
                        ; restart
                        0
                        ; dct
                        0
                    )
                    (gimp-message (string-append out-filename " ファイルを保存"))
                )

                ; イメージの削除
                (gimp-image-delete image)
            )
            (set! filelist (cdr filelist))
        )
    )
)

;============================================
;
; フィルター処理
;
;============================================
(define (AA-jisui-monotone-filter image drawable crop-size unsharp-flag)
    (gimp-message-set-handler CONSOLE)
    ; 切り抜き処理
    (if (> crop-size 0)
        (begin
            (gimp-message "切り抜き処理開始")
            (let*
                (
                    ; 関数の戻り値は、かならず List 形式になっているので、car が必須
                    (width (car (gimp-image-width image)))
                    (height (car (gimp-image-height image)))
                )
                (gimp-image-crop image
                    (- width (* crop-size 2))
                    (- height (* crop-size 2))
                    crop-size
                    crop-size
                )
            )
        )
    )

    ; 脱色処理
    (gimp-message "脱色処理開始")
    (gimp-desaturate drawable)

    ; ノイズ除去処理
    (gimp-message "ノイズ除去処理開始")
    (plug-in-despeckle RUN-NONINTERACTIVE image drawable
        ; 半径
        2
        ; 中央値
        1
        ; 黒レベル
        1
        ; 白レベル
        255
    )

    ; 色レベル調整処理
    (gimp-message "色レベル調整処理開始")
    (gimp-levels drawable HISTOGRAM-VALUE
        ; low-input
        60
        ; high-input
        225
        ; gamma
        1.0
        ; low-output
        0
        ; high-output
        255
    )

    ; アンシャープマスク処理
    (if (= unsharp-flag TRUE)
        (begin
            (gimp-message "アンシャープマスク処理開始")
            (plug-in-unsharp-mask RUN-NONINTERACTIVE image drawable
                ; 半径
                15.0
                ; 量
                4.00
                ; 閾値
                0
            )
        )
    )

    ; 再描画
    (gimp-displays-flush)
)

;============================================
;
; スクリプト定義
;
;============================================
(script-fu-register
    ; スクリプト名
    "AA-jisui-monotone-filter"
    ; メニュー名
    "<Image>/Filters/AA-Filters/jisui-monotone-filter"
    ; 詳細
    "自炊用フィルタ(モノトーン用)"
    ; 作成者
    "AbsoluteArea"
    ; コピーライト
    "copyright 2011, AbsoluteArea"
    ; 作成日
    "Jan 1, 2011"
    ; 動作モード指定
    "RGB*"

    SF-IMAGE "Image" 0
    SF-DRAWABLE "Drawable"  0
    SF-VALUE "Crop Size (pixels)" "30"
    SF-TOGGLE "UnSharp Mask" FALSE
);end of register


OCR 用フィルタ
切り抜き、脱色、ノイズ除去 、色レベル調整、脱色、二値化処理を行っている。
[ AA-jisui-OCR-filter.scm ]
;=====================================================================
; 自炊用フィルタ(OCR用)
; カレントフォルダ内の処理対象ファイル名パターンに一致する画像を開き、
; 画像処理後 Output フォルダへ保存するスクリプト
;
; コマンド入力例
; gimp-2.6 -i -b "(AA-jisui-ocr-filter-main \"C:\\image\\*.jpg\" \"C:\\image\\Output\" 30)" -b "(gimp-quit 0)"
;
; pattern: 処理対象ファイル名パターン
; outputdir: 出力ディレクトリ
; crop-size: クロップサイズ
;
;=====================================================================
(define (AA-jisui-ocr-filter-main pattern outputdir crop-size)
    (gimp-message-set-handler CONSOLE)
    (gimp-message "自炊用画像フィルタ(OCR用)処理開始")

    (let*
        ; カレントフォルダ内にあるファイルリスト取得
        ((filelist (cadr (file-glob pattern 1))))

        ; ループ処理
        (while (not (null? filelist))
            (let*
                (
                    ; 変数宣言および値の取得
                    (in-filename (car filelist))
                    (image (car (gimp-file-load RUN-NONINTERACTIVE in-filename in-filename)))
                    (drawable (car (gimp-image-get-active-layer image)))
                    ; 入力ファイル名から拡張子除いたものを生成
                    (out-filename-without-ext (AA-jisui-common-strip-base-filename in-filename))
                    ; 出力先フルパス文字列(拡張子を除く)を生成
                    (out-filepath-without-ext (string-append outputdir DIR-SEPARATOR out-filename-without-ext))
                )
                (gimp-message (string-append in-filename " ファイルの処理を開始"))

                ; 画像を処理
                (AA-jisui-ocr-filter image drawable crop-size)

                ; JPEG 形式でファイル保存
                (let*
                    (
                        ; ファイル名生成
                        (out-filename (string-append out-filepath-without-ext ".jpg"))
                    )
                    (file-jpeg-save RUN-NONINTERACTIVE image drawable out-filename out-filename
                        ; quality (0<=/<=1)
                        1
                        ; smoothing (0<=/<=1)
                        0
                        ; optimize (0/1)
                        1
                        ; progressive (0/1)
                        0
                        ; comment
                        ""
                        ; subsmp
                        0
                        ; baseline
                        1
                        ; restart
                        0
                        ; dct
                        0
                    )
                    (gimp-message (string-append out-filename " ファイルを保存"))
                )

                ; イメージの削除
                (gimp-image-delete image)
            )
            (set! filelist (cdr filelist))
        )
    )
)

;============================================
;
; フィルター処理
;
;============================================
(define (AA-jisui-ocr-filter image drawable crop-size)
    (gimp-message-set-handler CONSOLE)
    ; 切り抜き処理
    (if (> crop-size 0)
        (begin
            (gimp-message "切り抜き処理開始")
            (let*
                (
                    ; 関数の戻り値は、かならず List 形式になっているので、car が必須
                    (width (car (gimp-image-width image)))
                    (height (car (gimp-image-height image)))
                )
                (gimp-image-crop image
                    (- width (* crop-size 2))
                    (- height (* crop-size 2))
                    crop-size
                    crop-size
                )
            )
        )
    )

    ; 脱色処理
    (gimp-message "脱色処理開始")
    (gimp-desaturate drawable)

    ; ノイズ除去処理
    (gimp-message "ノイズ除去処理開始")
    (plug-in-despeckle RUN-NONINTERACTIVE image drawable
        ; 半径
        2
        ; 中央値
        1
        ; 黒レベル
        1
        ; 白レベル
        255
    )

    ; 色レベル調整処理
    (gimp-message "色レベル調整処理開始")
    (gimp-levels drawable HISTOGRAM-VALUE
        ; low-input
        60
        ; high-input
        225
        ; gamma
        1.0
        ; low-output
        0
        ; high-output
        255
    )

    ; アンシャープマスク処理
    (gimp-message "アンシャープマスク処理開始")
    (plug-in-unsharp-mask RUN-NONINTERACTIVE image drawable
        ; 半径
        15.0
        ; 量
        4.00
        ; 閾値
        0
    )

    ; 二値化処理
    (gimp-message "二値化処理開始")
    (gimp-threshold drawable 245 255)

    ; 再描画
    (gimp-displays-flush)
)

;============================================
;
; スクリプト定義
;
;============================================
(script-fu-register
    ; スクリプト名
    "AA-jisui-ocr-filter"
    ; メニュー名
    "<Image>/Filters/AA-Filters/jisui-ocr-filter"
    ; 詳細
    "自炊用フィルタ(OCR用)"
    ; 作成者
    "AbsoluteArea"
    ; コピーライト
    "copyright 2011, AbsoluteArea"
    ; 作成日
    "Jan 1, 2011"
    ; 動作モード指定
    "RGB*"

    SF-IMAGE "Image" 0
    SF-DRAWABLE "Drawable"  0
    SF-VALUE "Crop Size (pixels)" "30"
);end of register



■ バッチファイル
次に、Windows のバッチファイルを説明する。
各バッチを実行する前に、バッチ中の”GIMP_CMD”変数に、各自の環境に合わせた GIMP の実行ファイルのパスを指定する必要がある。これ重要。
使用方法は、処理対象のディレクトリをドラッグアンドドロップする。

実行する際には、GIMP が起動している必要は無い。また、GIMP が起動していても実行可能である。
各バッチは、複数のディレクトリを指定できるようになっている。
ディレクトリ名やファイル名は、スペースを含んでいても動作するようにがんばった。おかげで、バッドノウハウが沢山溜まった。


カラー用フィルタバッチ
[ color-filter.bat ]
@echo off
@echo 自炊用フィルタ(カラー用)
setlocal
set GIMP_CMD="C:\appli_x86\GIMP-2.0\bin\gimp-console-2.6.exe"
set GIMP_BAT_FUNC=AA-jisui-color-filter-main
set TARGET_FILES=*.jpg
set CROP_SIZE=10

@rem 引数チェック
if "%~1"=="" goto usage

@rem 全ての引数をループ処理する
:loop1
if "%~1"=="" goto execGimp
@rem まだ引数がある場合

dir "%~1" /A:D >nul 2>&1
if not errorlevel 1 goto dirCheckOk
@rem エラーの場合
@echo "%~1" が存在しないか、ディレクトリではありません。 1>&2
goto finish

:dirCheckOk

set INPUT_DIR=%~1\
set OUTPUT_DIR=%~1\Output
set GIMP_BATCH_OPT=%GIMP_BATCH_OPT% -b "(%GIMP_BAT_FUNC% \"%INPUT_DIR:\=\\%%TARGET_FILES%\" \"%OUTPUT_DIR:\=\\%\" %CROP_SIZE%)"
@rem 出力先ディレクトリ作成
if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
shift
goto loop1

:execGimp
@rem 画像処理実行
@echo %GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"
%GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"

goto finish

@rem 使用法表示
:usage
@echo 使い方:%~nx0 ^<dir^>

:finish
@echo 自炊用フィルタ(カラー用)処理が完了しました。何かキーを押してください。
pause > nul


モノトーン用フィルタバッチ
 [ monotone-filter.bat ]
@echo off
@echo 自炊用フィルタ(モノトーン用)
setlocal
set "GIMP_CMD=C:\appli_x86\GIMP-2.0\bin\gimp-console-2.6.exe"
set GIMP_BAT_FUNC=AA-jisui-monotone-filter-main
set TARGET_FILES=*.jpg
set CROP_SIZE=30
set UNSHARP_FLAG=TRUE

@rem 引数チェック
if "%~1"=="" goto usage

@rem 全ての引数をループ処理する
:loop1
if "%~1"=="" goto execGimp
@rem まだ引数がある場合

dir "%~1" /A:D >nul 2>&1
if not errorlevel 1 goto dirCheckOk
@rem エラーの場合
@echo "%~1" が存在しないか、ディレクトリではありません。 1>&2
goto finish

:dirCheckOk
set INPUT_DIR=%~1\
set OUTPUT_DIR=%~1\Output
set GIMP_BATCH_OPT=%GIMP_BATCH_OPT% -b "(%GIMP_BAT_FUNC% \"%INPUT_DIR:\=\\%%TARGET_FILES%\" \"%OUTPUT_DIR:\=\\%\" %CROP_SIZE% %UNSHARP_FLAG%)"
@rem 出力先ディレクトリ作成
if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
shift
goto loop1

:execGimp
@rem 画像処理実行
@echo %GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"
%GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"

goto finish

@rem 使用法表示
:usage
@echo 使い方:%~nx0 ^<dir^>

:finish
@echo 自炊用フィルタ(モノトーン用)処理が完了しました。何かキーを押してください。
pause > nul


OCR 用フィルタバッチ
[ ocr-filter.bat ]
@echo off
@echo 自炊用フィルタ(OCR用)
setlocal
set GIMP_CMD="C:\appli_x86\GIMP-2.0\bin\gimp-console-2.6.exe"
set GIMP_BAT_FUNC=AA-jisui-ocr-filter-main
set TARGET_FILES=*.jpg
set CROP_SIZE=30

@rem 引数チェック
if "%~1"=="" goto usage

@rem 全ての引数をループ処理する
:loop1
if "%~1"=="" goto execGimp
@rem まだ引数がある場合

dir "%~1" /A:D >nul 2>&1
if not errorlevel 1 goto dirCheckOk
@rem エラーの場合
@echo "%~1" が存在しないか、ディレクトリではありません。 1>&2
goto finish

:dirCheckOk
set INPUT_DIR=%~1\
set OUTPUT_DIR=%~1\Output
set GIMP_BATCH_OPT=%GIMP_BATCH_OPT% -b "(%GIMP_BAT_FUNC% \"%INPUT_DIR:\=\\%%TARGET_FILES%\" \"%OUTPUT_DIR:\=\\%\" %CROP_SIZE%)"
@rem 出力先ディレクトリ作成
if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"
shift
goto loop1

:execGimp
@rem 画像処理実行
@echo %GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"
%GIMP_CMD% -i %GIMP_BATCH_OPT% -b "(gimp-quit 0)"

goto finish

@rem 使用法表示
:usage
@echo 使い方:%~nx0 ^<dir^>

:finish
@echo 自炊用フィルタ(OCR用)処理が完了しました。何かキーを押してください。
pause > nul


最後に、便利ツールとして、ディレクトリ中の .jpg ファイルを 001 から始まる連番でリネームするバッチファイル。
このバッチファイルも、複数のディレクトリを一括指定できる。
拡張子を除くファイル名の末尾を指定文字数削って、連番をつけることも出来る。これは、既に連番が付いているものを付け直す用途を想定している。
[ renumber.bat ]
@echo off
@rem ===========================================
@rem 指定したディレクトリの *.jpg ファイルをファイル名順に連番つきでリネームする
@rem リネーム時にファイル名の末尾を削ってから連番を付与する指定もできる。img398.jpg -> img001.jpg など
@rem 複数のディレクトリを一括して処理可能
@rem スペースを含むディレクトリやファイルも処理可能
@rem ===========================================

setlocal enabledelayedexpansion

@rem 引数チェック
if "%~1"=="" goto usage
goto main

@rem メイン処理
:main
@rem 元ファイル名の末尾を削る桁数
set REPLACE_NUM_SIZE=3
@rem 連番の桁数
set NUM_SIZE=3
@rem 固定長表示用のパディング文字(NUM_SIZE - 1 文字設定すること)
set PAD_STR=00

@rem 引数の個数分ループする
:mainLoop

@rem 処理対象ディレクトリ
set targetDir=%~1

if "%targetDir%"=="" goto finish

@rem バッドノウハウ:"%~1\nul" でディレクトリ存在チェックをしようとすると、スペース入りディレクトリ名の判定に失敗する
@rem さらに Windows XP SP3 などでは、 "%~s1\nul" (短縮ファイル名)で判定しようとすると、
@rem バグのせいで正常に短縮ファイル名が返らないず、正しく判定ができない場合があるようだ
@rem しょうがないので、dir コマンドでディレクトリ一覧の取得に成功したら OK とした。
dir "%targetDir%" /A:D >nul 2>&1
if not errorlevel 1 goto dirCheckOk
@rem ディレクトリでなかった場合
@echo "%~1"  が存在しないか、ディレクトリではありません。
goto finish

:dirCheckOk

@rem 連番用カウンタ
set count=1

@rem *.jpg ファイルをファイル名でソートしてループ処理する
@rem tokens オプションを指定しないと、スペースを含むファイルが処理できない
for /f "tokens=*" %%I in ('dir /A-D /B /O:N "%TARGETDIR%\*.jpg"') do (
    set tmpnum=%PAD_STR%!count!
    set num=!tmpnum:~-%NUM_SIZE%!

    @rem 対象ファイルのフルパス
    set targetFileName=%targetDir%\%%~nxI

    @rem 連番付き新フルパスファイル名を生成
    set fileBase=%%~nI
    set fileExt=%%~xI
    if "%REPLACE_NUM_SIZE%"=="0" (
        @rem バッドノウハウ:%hoge:~0,-0% とすると、先頭0文字目から末尾から0文字目まで(つまり、そのままの値)にならず、空になる。
        set newFileBase=!fileBase!!num!
    ) else (
        set newFileBase=!fileBase:~0,-%REPLACE_NUM_SIZE%!!num!
    )
    set newFileName=!newFileBase!!fileExt!

    @rem ファイルリネーム実行
    @echo rename "!targetFileName!" "!newFileName!"
    rename "!targetFileName!" "!newFileName!"
    if ERRORLEVEL 1 (
        @echo バッチ処理を中断します。 1>&2
        goto finish
    )

    set /A count+=1
)

shift
goto mainLoop

goto finish


@rem 利用方法
:usage
@echo 使い方: %~nx0 ^<DIR^> [^<DIR^>] ...

:finish
@echo ファイルのリネーム処理が完了しました。何かキーを押してください。
@pause > nul


次回は、実際の作業方法などを解説していく。(予定・・・)