我有一系列 PNG 图像(
ABC_a.png
、ABC_b.png
、XYZ_a.png
、XYZ_b.png
、BCA_a.png
、BCA_b.png
等),并且想要组成相同代码(即名称)的每个图像文件夹内不带 _a
或 _b
) 的图像。
手动,代码将如下所示:
magick composite ABC_b.png ABC_a.png ABC.png
magick composite XYZ_b.png XYZ_a.png XYZ.png
magick composite BCA_b.png BCA_a.BCA BCA.png
...
...部分透明图像
_b
将被放置在 _a
的“顶部”,并且输出文件的名称将失去其 _a
/_b
后缀。
我环顾四周,通过
mogrify
或 for 循环 (FOR %i IN (*.png) DO magick composite ...
) 尝试了几种方法,但无法自动化。也许使用两个单独的文件夹并使用相同的图像名称(不带后缀)会有所帮助,但我不确定......
我很感激任何提示。请注意,我需要在 Windows CMD 或 PowerShell 中工作才能实现这一点。
可以使用以下批处理文件来完成此任务:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ImageMagick=magick.exe"
if exist "*!*_a.png" goto ExtendedVersion
setlocal EnableDelayedExpansion
for %%I in (*_a.png) do (
set "FileNameA=%%~nI"
set "FileName=!FileNameA:~0,-2!%%~xI"
if not exist "!FileName!" "!ImageMagick!" composite "!FileNameA:~0,-1!b%%~xI" "!FileNameA!%%~xI" "!FileName!"
)
endlocal
goto EndBatch
:ExtendedVersion
echo INFO: Extended version required because of a PNG file with exclamation marks.
for %%I in (*_a.png) do (
set "FileNameA=%%~nI"
setlocal EnableDelayedExpansion
set "FileName=!FileNameA:~0,-2!%%~xI"
if not exist "!FileName!" "!ImageMagick!" composite "!FileNameA:~0,-1!b%%~xI" "!FileNameA!%%~xI" "!FileName!"
endlocal
)
:EndBatch
endlocal
首先使用前两个命令行定义所需的执行环境。
接下来,使用该程序的文件名定义环境变量
ImageMagick
。最好添加完整路径,因为在这种情况下,cmd.exe
不需要使用环境变量 magick.exe
的字符串值中的文件扩展名在当前目录和所有目录中搜索 PATH
每次执行 ImageMagick之前的环境变量
PATHEXT
。使用 ImageMagick 的完全限定文件名将避免对十多个要处理的 PNG 文件进行数百甚至数千次文件系统访问。
第四行命令行中的IF条件快速检查文件名中是否存在文件扩展名
_a
之前包含一个或多个感叹号且文件名中不区分大小写.png
的PNG文件。如果此条件成立,则需要处理循环的扩展版本。
标准版本首先启用所需的延迟扩展。然后使用 FOR 循环依次处理一个 PNG 文件,文件名中的
_a
位于文件扩展名 .png
之前,不区分大小写。
不带文件扩展名的当前文件名
.png
首先分配给环境变量FileNameA
。
接下来,使用字符串替换从环境变量的字符串值中获取
FileNameA
不带最后两个字符的文件名 _a
与分配给环境变量 .png
的文件扩展名 FileName
连接。
如果文件扩展名前的文件名中尚不存在不以
_a
结尾的 PNG 文件,则接下来执行 ImageMagick,第一个参数是通过再次使用字符串替换来确定的相应 _b.png
文件分配给环境变量 FileName
的文件名字符串,不带最后一个字符 a
,与 b
和文件扩展名 .png
以及文件扩展名作为第二个参数的 _a.png
文件以及不带 _a
的文件名
作为第三个参数。
循环后的命令ENDLOCAL恢复启用延迟扩展之前的先前环境,命令GOTO指示Windows命令处理器继续处理批处理文件,其命令行位于标签
EndBatch
下方,其中还包含一个ENDLOCAL 在开始批处理文件处理时恢复环境。
扩展版与标准版几乎相同。不同之处在于,将不带文件扩展名的当前
_a.png
文件的文件名分配给环境变量 FileNameA
时,不会启用延迟变量扩展。这可以避免将文件名中的感叹号解释为延迟扩展变量引用的开头/结尾,从而导致在将文件名字符串分配给环境变量之前对其进行操作,因为在已启用延迟扩展的情况下会发生这种情况。
扩展版本在循环内启用下一个延迟变量扩展,与标准版本相同,并在处理下一个
_a.png
文件之前最终恢复之前的环境。
扩展版本速度较慢,因为每次执行 SETLOCAL 都会在后台进行环境变量列表复制和其他操作,如此答案中详细说明。循环中需要使用命令 ENDLOCAL 以避免处理大量 PNG 文件时出现堆栈溢出。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?