powershell 为什么参数-PointSize默认值不被ImageMagick内部接受?

eqoofvh9  于 2023-05-07  发布在  Shell
关注(0)|答案(1)|浏览(126)

下面是一个函数,它可以让我生成一个带有标题/文本的图像。

Function New-Image{
    param(
        [Parameter(Mandatory)]
        $Destination,
        
        [Parameter(ValueFromPipeline)]
        [string]$Value,

        [string]$Dimentions,
        [int]$PointSize = 500,
        [string]$Font,
        [string]$FontColour,
        [string]$BackgroundColor,
        [string]$BorderColor,
        [String]$BorderStroke
    )
    $PSBoundParameters.Keys += If ($PSBoundParameters.Keys -notcontains 'PointSize'){"PointSize"}
    $magickArgs = @(
        switch ($PSBoundParameters.Keys){
            'PointSize'       { '-pointSize', $PointSize }
            'Font'            { '-font', $Font}
            'BackgroundColor' { '-background', $BackgroundColor}
            'FontColour'      { '-fill', $FontColour }
            'Value'           { "label:$value" }  # Exception: ONE token!
            'BorderColor'     { '-bordercolor', $BorderColor }
            'BorderStroke'    { '-border', $BorderStroke }
        }
    )
    $magickArgs
    . 'C:\Program Files\ImageMagick-7.1.0-Q16-HDRI\magick.exe' @magickArgs $Destination
}

参数-Pointsize让我决定图像尺寸或文本的字体大小。我发现自己95%的时间都在使用-Pointsize 500,因此决定将500设置为该参数的默认值。
但是函数的设计方式(出于PowerShell将参数传递给本机命令的必要性)使我很难实现。
似乎在顶部声明[String]$PointSize = 500,-PointSize不会包含在$PSBoundParameters.Keys中,因此switch命令永远不会看到-Pointsize参数。
我用$PSBoundParameters.Keys += If ($PSBoundParameters.Keys -notcontains 'PointSize'){"PointSize"}修复了这个问题,但每当我用以下命令进行测试时:

New-Image "hellow world" -Destination "test3.png"

文本仍然很小,好像ImageMagick从未收到-PointSize参数和值,但打印$magicArgs清楚地显示它有:

New-Image "hellow world" -Destination "test3.png"  

label:hellow world   # Output
-pointSize  
500

手动声明值为500-PointSize可以正常工作。生成图像的文本非常大。
任何帮助将不胜感激!

huus2vyu

huus2vyu1#

自动$PSBoundParameters变量只包含 * 显式 * 绑定的参数及其值(即那些由调用者提供的),这显然不包括 default 值。

您的想法是正确的--如果调用者没有传递-PointSize参数,则向$PSBoundParameters添加具有所需默认值的PointSize条目--但实现存在缺陷;使用以下命令代替:[1]

if (-not $PSBoundParameters.ContainsKey('PointSize')) {
  $PSBoundParameters['PointSize'] = $PointSize
}

至于你尝试了什么

# !! Adds an entry whose key is literally "Keys", 
# !! with literal value "PointSize"
$PSBoundParameters.Keys += If ($PSBoundParameters.Keys -notcontains 'PointSize'){"PointSize"}

即使在概念上尝试 assign 到- read-only -.Keys属性也不会起作用:只有.Add()方法和索引语法/点表示法(见下文)可以用于通过添加整个 * 条目 * 来增长字典,其中 * 条目的键然后自动反映在.Keys集合中。
PowerShell所做的-也许令人惊讶的是-是当你分配给.Keys时,它创建了一个 * 新条目 *,其文字键值是Keys,因为-作为语法上的方便- * 点符号 * 可以代替 * 索引符号 *;即,$PSBoundParameters.Keys = ...等效于$PSBoundParameters['Keys'] = ...
换句话说:你的尝试创建了一个带有文本键Keys和文本值PointSize的新条目,这意味着该条目具有错误的键(应该是PointSize)和值(应该是$PointSize的值)。
[1]请注意,修改 automatic 变量指向的对象 * 通常 * 不是一个好主意,但在这个特定情况下,它被明确地提到为一种可能性(从顶部链接的帮助主题,强调添加):“您可以使用它[$PSBoundParameters]来显示 * 或更改 * 参数的当前值,或将参数值传递给另一个脚本或函数。”
相比之下,给自动变量(例如$PSBoundParameters = ...)分配一个不同的值从来都不是一个好主意(而且经常失败)。

相关问题