有没有办法用imagemagick合成一批图像?

问题描述 投票:0回答:1

我有一系列 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 中工作才能实现这一点。

image-processing cmd imagemagick png composite
1个回答
2
投票

可以使用以下批处理文件来完成此任务:

@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 /?
© www.soinside.com 2019 - 2024. All rights reserved.