我正在尝试编写一个单行代码,该代码获取目录中tif文件的唯一ID,然后运行ImageMajick的转换将它们组合成多页tif:
convert ..image_dataua-nws_00000991_001.tif ..image_dataua-nws_00000991_002.tif ..image_dataua-nws_00000991_003.tif ..image_dataua-nws_00000991_004.tif ua-nws_00000991_all.tif
这有效,但我正在尝试为一堆 id 自动化它,每个 id 有几个 tif。目前,我只使用一个id并使用"echo"而不是转换:
echo "ua-nws_00000991" | % { $id=$_; ls ../image_data | ? { $_.FullName -match $id } | % {
echo $_.FullName } | Join-String -Separator '" "' | % { echo '"'$_'"' $id"_all.tif" }
}
但是我在将文件列表转换为参数列表时遇到问题。我得到以下内容(我已经手动制作了相对于在线发布的路径):
"
.image_dataua-nws_00000991_001.tif" ".image_dataua-nws_00000991_002.tif" ".image_dataua-nws_00000991_003.tif" "C:Daniels_StuffClassesCurrentgrad_aiprojectrepoarticle-reconstructionimage_dataua-nws_00000991_004.tif"
ua-nws_00000991_all.tif
在我添加双引号之前,convert将所有最终$_
解释为一个参数。我正在添加引号以强制转换将它们视为多个参数。但我似乎无法摆脱那个换行符。我认为这可能是由最终echo
引起的,但是如果我将其替换为转换,我会得到以下结果:
convert.exe: unable to open module file `C:Program FilesImageMagick-6.9.2-Q16modulescodersIM_MOD_RL_ABSOLUTEPATHTOMYIMAGESIMAGE_DATAUA-NWS_00000991_001.TIF C_.dll': No such file or directory @ warning/module.c/GetMagickModulePath/674.
convert.exe: no decode delegate for this image format `ABSOLUTEPATHTOMYIMAGESIMAGE_DATAUA-NWS_00000991_001.TIF C' @ error/constitute.c/ReadImage/501.
convert.exe: no images defined `ua-nws_00000991_all.tif' @ error/convert.c/ConvertImageCommand/3241.
虽然我不理解Powershell的疯狂语法,但ImageMagick有两个方面可能会帮助你......
方面 1 - 标准上的文件名
首先,您可以在ImageMagick的stdin上传递文件名列表以合并到单个 TIF 中,而不是作为参数。因此,如果您有一本书的 3 页,在 3 个文件中称为p1.tif
、p2.tif
和p3.tif
,而不是 做:
convert p*.tif book.tif
你也可以做
dir /b/s p*tif | convert @- book.tif
当我使用DIR /B/S
生成上述名称时,我希望您希望将其替换为您的 Powershell 命令。
看点 2 - 单个管道下达多个图像
其次,您可以使用"Magick Image File Format">(MIFF
)流将来自convert
多次调用的多个图像通过管道传输到convert
的进一步最终调用:
下面是一个示例,其中对convert
的两个调用都分别将图像发送到最终convert
,该从其 MIFF 输入流中加入图像:
( convert p1.tif MIFF:- & convert p2.tif MIFF:- ) | convert MIFF:- book.tif
这是同一事物的一个略有不同的示例:
FOR files *.TIF; DO
IF this file has the correct id
convert $this MIFF:-
ENDIF
ENDDO | convert MIFF:- book.tif
我不知道Join-String
是从哪里来的,但我只能猜测它坏了——因为我看不到换行符来自哪里。
将一些测试文件放在一个文件夹中:
Name
----
ua-nws_00000991_001.tif
ua-nws_00000991_002.tif
ua-nws_00000991_003.tif
ua-nws_00000991_004.tif
ua-nws_00000992_001.tif
ua-nws_00000992_002.tif
ua-nws_00000992_003.tif
ua-nws_00000992_004.tif
用Get-ChildItem
(gci
)列出它们,并通过从文件名中删除尾随数字来分组它们(Group-Object
,又名group
):
PS D:tNew folder> gci *.tif | group { $_.Name -replace '_d+.tif$' }
Count Name Group
----- ---- -----
4 ua-nws_00000991 {D:tNew folderua-nws_00000991_001.tif, D:tNew folderua-nws_00000991_002.tif, D:tNew folderua-nws...
4 ua-nws_00000992 {D:tNew folderua-nws_00000992_001.tif, D:tNew folderua-nws_00000992_002.tif, D:tNew folderua-nws...
现在我们有组,其中组名称是映像 ID,该 ID 的文件列表是组成员。整洁。现在运行转换一次foreach
(%
)组,方法是将完整的文件名作为要转换的参数,并从组ID($_.name
)生成一个新的文件名,末尾带有_full.tif
:
gci *.tif | group { $_.Name -replace '_d+.tif$' } |% { Start-Process convert -ArgumentList (@($_.group.fullname) + @("$($_.Name)_full.tif"))}
这可能无法按原样工作,我没有安装convert
来尝试它,您需要调整路径。但我认为这种方法会奏效。
您可以尝试以下操作:
get-childitem "image_data" -recurse -filter ua-nws_00000991*.tif | % { convert $_.Fullname }
返回"image_data"目录中的所有 tif 文件,并为每个找到的 tif 文件调用convert
。
希望有帮助