如何使用 ImageMagick 在 Windows 批处理文件中捕获图像比较结果
How to capture image comparison result in Windows batch file, using ImageMagick
我正在尝试创建一个 Windows bat 文件以在 Windows 10 上使用 GhostScript 和 ImageMagick 7.0.9 比较两个 PDF 文件。第一步为每个页面创建 PNG 文件并且 magick.exe 与 "compare" 命令(在 Windows 上没有单独的 compare.exe)比较图像。不幸的是,即使图像不匹配,%errorlevel" 仍然为 0。
作为一种变通方法,我尝试使用 magick compare 的输出,它在成功时将“0 (0)”发送到 stderr。然而,在这里我未能将 stderr 捕获到环境变量中,可能是因为某些变量范围问题或遗漏了其他内容。 magick 输出被定向到临时文件,然后用 set /P 加载。通过在 magick 比较之后添加暂停,我可以确认 txt 文件在匹配文件上包含“0 (0)”。 echo %SCRIPTRESULT% 什么都不打印。
set /P SCRIPTRESULT=<result/stdtmp.txt
整个bat文件:
@echo off
@rem we assume the current directory is root folder of the test that is being run
@rem get parameters
setlocal
set JOBNAME=%1
set FILETYPE=%2
set PAGECOUNT=%3
set PAGE=1
set FAILPAGE=1
set SCRIPTRESULT=
@rem create the PNG files for two PDFs in ./result/ and ./result_t/ folders
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_CURR%%d.png -r200 ./result_t/%JOBNAME%.%FILETYPE%
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_ORIG%%d.png -r200 ./result/%JOBNAME%.%FILETYPE%
@rem gs produces separate PNG for each PDF or PostScript page and we specify the expected count as parameter to this script
FOR /L %%P IN (1,1,%PAGECOUNT%) do (
set PAGE=%%P
rem echo Page %PAGE% of %PAGECOUNT%
magick compare -metric MAE ./result/%JOBNAME%_%FILETYPE%_CURR%PAGE%.png ./result/%JOBNAME%_%FILETYPE%_ORIG%PAGE%.png ./result/%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png 2> result/stdtmp.txt
rem Errorlevel in Windows ImageMagick is always 0 so we need to observe sderr instead?
echo The errorlevel is %errorlevel%
set /P SCRIPTRESULT=<result/stdtmp.txt
echo Compare returned %SCRIPTRESULT%
del /Q .\result\stdtmp.txt
del /Q ".\result\%JOBNAME%_%FILETYPE%_CURR%PAGE%.png"
del /Q ".\result\%JOBNAME%_%FILETYPE%_ORIG%PAGE%.png"
IF "%SCRIPTRESULT%" == "0 (0)" (
echo Deleting .\result\%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png
del /Q ".\result\%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png"
) ELSE (
echo Failed at page %PAGE%
set /A FAILPAGE=%PAGE%
)
)
echo Outside the loop SCRIPTRESULT=%SCRIPTRESULT%
IF "%SCRIPTRESULT%" == "0 (0)" (
echo Files compare OK >&2
)
IF NOT "%SCRIPTRESULT%" == "0 (0)" (
echo Visual compare failed, see ./result/%JOBNAME%_%FILETYPE%_DIFF%FAILPAGE%.png >&2
)
一个人可以运行这个脚本作为
compare.bat filename pdf 1
这假设我们有 .\result\filename.pdf 和 .\result_t\filename.pdf,每个都有 1 页。更复杂的是,这个比较脚本旨在通过另一个脚本的调用来使用。在那种情况下,我看到输出:
The errorlevel is 0
Compare returned
Fail at page 1
Outside the loop SCRIPTRESULT=0 (0)
Files compare OK
那么显然循环外的 SCRIPTRESULT 值如预期的那样是“0 (0)”,但在 FOR 循环内不是?添加 setlocal ENABLEDELAYEDEXPANSION 没有任何明显的效果。
发布脚本的功能版本,感谢评论者。假设有两个单页 PDF 文件 .\result\some.pdf 和 .\result_t\some.pdf,运行 比较:
compare.bat some pdf 1
它也适用于 PostScript 或 GhostScript 可以呈现的任何其他内容。匹配失败将在 'result' 文件夹中留下视觉差异文件。
@rem we assume the current directory is root folder of the test that is being run
@echo off
@setlocal ENABLEDELAYEDEXPANSION
set JOBNAME=%1
set FILETYPE=%2
set PAGECOUNT=%3
set FAILPAGE=0
@rem Using either pngalpha or png16m device
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_CURR%%d.png -r200 ./result_t/%JOBNAME%.%FILETYPE%
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_ORIG%%d.png -r200 ./result/%JOBNAME%.%FILETYPE%
@rem gs produces separate PNG for each PDF or PostScript page and we specify the expected count as parameter to this script
@rem Note that we do not catch case where the result has more pages than template
FOR /L %%P IN (1,1,%PAGECOUNT%) do (
magick compare -metric MAE "./result/%JOBNAME%_%FILETYPE%_CURR%%P.png" "./result/%JOBNAME%_%FILETYPE%_ORIG%%P.png" "./result/%JOBNAME%_%FILETYPE%_DIFF%%P.png" 2>nul
rem echo The errorlevel is !errorlevel!
IF !errorlevel! == 0 (
del /Q ".\result\%JOBNAME%_!FILETYPE!_DIFF%%P.png"
) ELSE (
echo Difference on page %%P
set /A FAILPAGE=%%P
)
del /Q ".\result\%JOBNAME%_!FILETYPE!_CURR%%P.png"
del /Q ".\result\%JOBNAME%_!FILETYPE!_ORIG%%P.png"
)
IF !FAILPAGE! == 0 (
echo Files compare OK >&2
EXIT /B 0
) else (
echo Visual compare failed, see ./result/%JOBNAME%_!FILETYPE!_DIFF!FAILPAGE!.png >&2
EXIT /B 1
)
我正在尝试创建一个 Windows bat 文件以在 Windows 10 上使用 GhostScript 和 ImageMagick 7.0.9 比较两个 PDF 文件。第一步为每个页面创建 PNG 文件并且 magick.exe 与 "compare" 命令(在 Windows 上没有单独的 compare.exe)比较图像。不幸的是,即使图像不匹配,%errorlevel" 仍然为 0。
作为一种变通方法,我尝试使用 magick compare 的输出,它在成功时将“0 (0)”发送到 stderr。然而,在这里我未能将 stderr 捕获到环境变量中,可能是因为某些变量范围问题或遗漏了其他内容。 magick 输出被定向到临时文件,然后用 set /P 加载。通过在 magick 比较之后添加暂停,我可以确认 txt 文件在匹配文件上包含“0 (0)”。 echo %SCRIPTRESULT% 什么都不打印。
set /P SCRIPTRESULT=<result/stdtmp.txt
整个bat文件:
@echo off
@rem we assume the current directory is root folder of the test that is being run
@rem get parameters
setlocal
set JOBNAME=%1
set FILETYPE=%2
set PAGECOUNT=%3
set PAGE=1
set FAILPAGE=1
set SCRIPTRESULT=
@rem create the PNG files for two PDFs in ./result/ and ./result_t/ folders
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_CURR%%d.png -r200 ./result_t/%JOBNAME%.%FILETYPE%
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_ORIG%%d.png -r200 ./result/%JOBNAME%.%FILETYPE%
@rem gs produces separate PNG for each PDF or PostScript page and we specify the expected count as parameter to this script
FOR /L %%P IN (1,1,%PAGECOUNT%) do (
set PAGE=%%P
rem echo Page %PAGE% of %PAGECOUNT%
magick compare -metric MAE ./result/%JOBNAME%_%FILETYPE%_CURR%PAGE%.png ./result/%JOBNAME%_%FILETYPE%_ORIG%PAGE%.png ./result/%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png 2> result/stdtmp.txt
rem Errorlevel in Windows ImageMagick is always 0 so we need to observe sderr instead?
echo The errorlevel is %errorlevel%
set /P SCRIPTRESULT=<result/stdtmp.txt
echo Compare returned %SCRIPTRESULT%
del /Q .\result\stdtmp.txt
del /Q ".\result\%JOBNAME%_%FILETYPE%_CURR%PAGE%.png"
del /Q ".\result\%JOBNAME%_%FILETYPE%_ORIG%PAGE%.png"
IF "%SCRIPTRESULT%" == "0 (0)" (
echo Deleting .\result\%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png
del /Q ".\result\%JOBNAME%_%FILETYPE%_DIFF%PAGE%.png"
) ELSE (
echo Failed at page %PAGE%
set /A FAILPAGE=%PAGE%
)
)
echo Outside the loop SCRIPTRESULT=%SCRIPTRESULT%
IF "%SCRIPTRESULT%" == "0 (0)" (
echo Files compare OK >&2
)
IF NOT "%SCRIPTRESULT%" == "0 (0)" (
echo Visual compare failed, see ./result/%JOBNAME%_%FILETYPE%_DIFF%FAILPAGE%.png >&2
)
一个人可以运行这个脚本作为
compare.bat filename pdf 1
这假设我们有 .\result\filename.pdf 和 .\result_t\filename.pdf,每个都有 1 页。更复杂的是,这个比较脚本旨在通过另一个脚本的调用来使用。在那种情况下,我看到输出:
The errorlevel is 0
Compare returned
Fail at page 1
Outside the loop SCRIPTRESULT=0 (0)
Files compare OK
那么显然循环外的 SCRIPTRESULT 值如预期的那样是“0 (0)”,但在 FOR 循环内不是?添加 setlocal ENABLEDELAYEDEXPANSION 没有任何明显的效果。
发布脚本的功能版本,感谢评论者。假设有两个单页 PDF 文件 .\result\some.pdf 和 .\result_t\some.pdf,运行 比较:
compare.bat some pdf 1
它也适用于 PostScript 或 GhostScript 可以呈现的任何其他内容。匹配失败将在 'result' 文件夹中留下视觉差异文件。
@rem we assume the current directory is root folder of the test that is being run
@echo off
@setlocal ENABLEDELAYEDEXPANSION
set JOBNAME=%1
set FILETYPE=%2
set PAGECOUNT=%3
set FAILPAGE=0
@rem Using either pngalpha or png16m device
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_CURR%%d.png -r200 ./result_t/%JOBNAME%.%FILETYPE%
gswin64 -dSAFER -dBATCH -dNOPAUSE -dQUIET -sDEVICE=png16m -sOutputFile=./result/%JOBNAME%_%FILETYPE%_ORIG%%d.png -r200 ./result/%JOBNAME%.%FILETYPE%
@rem gs produces separate PNG for each PDF or PostScript page and we specify the expected count as parameter to this script
@rem Note that we do not catch case where the result has more pages than template
FOR /L %%P IN (1,1,%PAGECOUNT%) do (
magick compare -metric MAE "./result/%JOBNAME%_%FILETYPE%_CURR%%P.png" "./result/%JOBNAME%_%FILETYPE%_ORIG%%P.png" "./result/%JOBNAME%_%FILETYPE%_DIFF%%P.png" 2>nul
rem echo The errorlevel is !errorlevel!
IF !errorlevel! == 0 (
del /Q ".\result\%JOBNAME%_!FILETYPE!_DIFF%%P.png"
) ELSE (
echo Difference on page %%P
set /A FAILPAGE=%%P
)
del /Q ".\result\%JOBNAME%_!FILETYPE!_CURR%%P.png"
del /Q ".\result\%JOBNAME%_!FILETYPE!_ORIG%%P.png"
)
IF !FAILPAGE! == 0 (
echo Files compare OK >&2
EXIT /B 0
) else (
echo Visual compare failed, see ./result/%JOBNAME%_!FILETYPE!_DIFF!FAILPAGE!.png >&2
EXIT /B 1
)