尽管参数正确,但从参数错误的 powershell 调用 GetPixel
Calling GetPixel from powershell with param error despite correct params
下面的代码片段是调试器的输出。
Exception calling "GetPixel" with "2" argument(s): "Parameter must be positive and < Height.
Parameter name: y"
At C:\dropbox\Workspace\PowerShellTest\mapGenerator\mapGenerator.ps1:51 char:16
+ if(($map.GetPixel($x, ($y+1)) -eq "ff000000") -or ($map.GetPixel(($x ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
Hit Line breakpoint on 'C:\dropbox\Workspace\PowerShellTest\mapGenerator\mapGenerator.ps1:51'
[DBG]: PS C:\dropbox\Workspace\PowerShellTest\mapGenerator>> $y
5
[DBG]: PS C:\dropbox\Workspace\PowerShellTest\mapGenerator>> $map.Height
7
我根本没有收到此错误消息。
"Parameter must be positive and < Height."
好的。但是参数是 (5+1),所以是正数,而参数是 (5+1),所以 <7
MCVE代码
编辑 1:
删除了 MCVE 代码 - 我在 MCVE 中发现了一个错误,删除后,错误消息也消失了。现在回头看看我原来的代码有没有同样的错误。
编辑 2:这真令人气愤。我为 $x 和 $y 值插入了一个写入输出,只是为了确保我没有任何错误值(例如,检查坐标为 0 的像素下方,或坐标为 map.height 的像素上方 插入写输出使其余代码运行正确。删除写输出使代码再次停止工作。写输出是否在幕后强制执行某些操作?
编辑 3:制作保留这种奇怪行为的 MCVE 非常困难,所以我会给你它发生的脚本。
function markCoastline ($landArray, $map)
{
foreach ($square in $landArray)
{
$x = $square[0]
$y = $square[1]
$top = ($y -eq $map.Height-1)
$bot = ($y -eq 0)
$lef = ($x -eq 0)
$rig = ($x -eq $map.Width-1)
Write-Output $x
Write-Output $y
if( $bot -and $left)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000")-or ($map.GetPixel(($x+1), $y).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top -and $left)
{
if(($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $bot -and $rig)
{
if(($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y+1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top -and $rig)
{
if(($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $lef)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $bot)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $rig)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000")-or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top)
{
if(($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
else
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
}
}
#First, get a BMP image
$openFile = New-Object -TypeName System.Windows.Forms.OpenFileDialog
$openFile.AddExtension = $true
$openFile.Filter = 'Bitmap Picture (*.bmp)|*.bmp|All Files|*.*'
$openFile.Multiselect = $false
$openFile.FilterIndex = 0
$openFile.InitialDirectory = "$HOME\Documents"
$openFile.RestoreDirectory = $true
$openFile.ShowReadOnly = $true
$openFile.ReadOnlyChecked = $false
$openFile.Title = 'Select a seed picture (BMP only)'
$openFile.showDialog()
$map = New-Object System.Drawing.Bitmap($openFile.Filename)
$landPixels = @()
$oceanPixels = @()
#Second: Find land/ocean
for ($x = 0; $x -lt $map.Width; $x++)
{
for ($y = 0; $y -lt $map.Height; $y++)
{
$current = $map.GetPixel($x, $y)
if($current.Name -eq "ff000000")
{
$ocean = @($x, $y)
$oceanPixels += , $ocean
}
else
{
$land = @($x, $y)
$landPixels += , $land
}
}
}
#Third, paint coastline green:
markCoastline $landPixels $map
$map.save("b8fcf4351caf4b00af8eb0fa2e5bc17a.bmp")
第 16 行和第 17 行有一个写入输出。删除它们,脚本给出了上面提到的原始问题 - 声称 $y 不适合作为 GetPixel 函数的参数。保持它和代码 运行 完全符合预期。
在您的代码中有两个地方使用 $left
而不是 $lef
。不管 Write-Output
,我仍然收到该错误消息。错误消息只是隐藏在所有输出之下,但它仍然在这里。
我建议您在调试代码时使用 Set-StrictMode -Version Latest
和 $ErrorActionPreference='Inquire'
。用它们更容易发现错误。
P.S.
不使用数组加法,而是重新分配数组或每次加法,而是使用列表:
$landPixels = New-Object System.Collections.Generic.List[object]
$oceanPixels = New-Object System.Collections.Generic.List[object]
for ($x = 0; $x -lt $map.Width; $x++)
{
for ($y = 0; $y -lt $map.Height; $y++)
{
$current = $map.GetPixel($x, $y)
if($current.Name -eq "ff000000")
{
$oceanPixels.Add(($x,$y))
}
else
{
$landPixels.Add(($x,$y))
}
}
}
P.P.S.
$x,$y = $square
P.P.P.S
if(
(($y+1 -lt $map.Height) -and ($map.GetPixel($x, ($y+1)).Name -eq "ff000000")) -or
(($y-1 -gt 0) -and ($map.GetPixel($x, ($y-1)).Name -eq "ff000000")) -or
(($x+1 -lt $map.Width) -and ($map.GetPixel(($x+1), $y).Name -eq "ff000000")) -or
(($x-1 -gt 0) -and ($map.GetPixel(($x-1), $y).Name -eq "ff000000"))
)
{
$map.SetPixel($x, $y, "lime")
}
下面的代码片段是调试器的输出。
Exception calling "GetPixel" with "2" argument(s): "Parameter must be positive and < Height.
Parameter name: y"
At C:\dropbox\Workspace\PowerShellTest\mapGenerator\mapGenerator.ps1:51 char:16
+ if(($map.GetPixel($x, ($y+1)) -eq "ff000000") -or ($map.GetPixel(($x ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
Hit Line breakpoint on 'C:\dropbox\Workspace\PowerShellTest\mapGenerator\mapGenerator.ps1:51'
[DBG]: PS C:\dropbox\Workspace\PowerShellTest\mapGenerator>> $y
5
[DBG]: PS C:\dropbox\Workspace\PowerShellTest\mapGenerator>> $map.Height
7
我根本没有收到此错误消息。
"Parameter must be positive and < Height."
好的。但是参数是 (5+1),所以是正数,而参数是 (5+1),所以 <7
MCVE代码
编辑 1: 删除了 MCVE 代码 - 我在 MCVE 中发现了一个错误,删除后,错误消息也消失了。现在回头看看我原来的代码有没有同样的错误。
编辑 2:这真令人气愤。我为 $x 和 $y 值插入了一个写入输出,只是为了确保我没有任何错误值(例如,检查坐标为 0 的像素下方,或坐标为 map.height 的像素上方 插入写输出使其余代码运行正确。删除写输出使代码再次停止工作。写输出是否在幕后强制执行某些操作?
编辑 3:制作保留这种奇怪行为的 MCVE 非常困难,所以我会给你它发生的脚本。
function markCoastline ($landArray, $map)
{
foreach ($square in $landArray)
{
$x = $square[0]
$y = $square[1]
$top = ($y -eq $map.Height-1)
$bot = ($y -eq 0)
$lef = ($x -eq 0)
$rig = ($x -eq $map.Width-1)
Write-Output $x
Write-Output $y
if( $bot -and $left)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000")-or ($map.GetPixel(($x+1), $y).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top -and $left)
{
if(($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $bot -and $rig)
{
if(($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y+1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top -and $rig)
{
if(($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $lef)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $bot)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $rig)
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000")-or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
elseif( $top)
{
if(($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
else
{
if(($map.GetPixel($x, ($y+1)).Name -eq "ff000000") -or ($map.GetPixel(($x+1), $y).Name -eq "ff000000") -or ($map.GetPixel(($x-1), $y).Name -eq "ff000000") -or ($map.GetPixel($x, ($y-1)).Name -eq "ff000000"))
{
$map.SetPixel($x, $y, "lime")
}
}
}
}
#First, get a BMP image
$openFile = New-Object -TypeName System.Windows.Forms.OpenFileDialog
$openFile.AddExtension = $true
$openFile.Filter = 'Bitmap Picture (*.bmp)|*.bmp|All Files|*.*'
$openFile.Multiselect = $false
$openFile.FilterIndex = 0
$openFile.InitialDirectory = "$HOME\Documents"
$openFile.RestoreDirectory = $true
$openFile.ShowReadOnly = $true
$openFile.ReadOnlyChecked = $false
$openFile.Title = 'Select a seed picture (BMP only)'
$openFile.showDialog()
$map = New-Object System.Drawing.Bitmap($openFile.Filename)
$landPixels = @()
$oceanPixels = @()
#Second: Find land/ocean
for ($x = 0; $x -lt $map.Width; $x++)
{
for ($y = 0; $y -lt $map.Height; $y++)
{
$current = $map.GetPixel($x, $y)
if($current.Name -eq "ff000000")
{
$ocean = @($x, $y)
$oceanPixels += , $ocean
}
else
{
$land = @($x, $y)
$landPixels += , $land
}
}
}
#Third, paint coastline green:
markCoastline $landPixels $map
$map.save("b8fcf4351caf4b00af8eb0fa2e5bc17a.bmp")
第 16 行和第 17 行有一个写入输出。删除它们,脚本给出了上面提到的原始问题 - 声称 $y 不适合作为 GetPixel 函数的参数。保持它和代码 运行 完全符合预期。
在您的代码中有两个地方使用 $left
而不是 $lef
。不管 Write-Output
,我仍然收到该错误消息。错误消息只是隐藏在所有输出之下,但它仍然在这里。
我建议您在调试代码时使用 Set-StrictMode -Version Latest
和 $ErrorActionPreference='Inquire'
。用它们更容易发现错误。
P.S.
不使用数组加法,而是重新分配数组或每次加法,而是使用列表:
$landPixels = New-Object System.Collections.Generic.List[object]
$oceanPixels = New-Object System.Collections.Generic.List[object]
for ($x = 0; $x -lt $map.Width; $x++)
{
for ($y = 0; $y -lt $map.Height; $y++)
{
$current = $map.GetPixel($x, $y)
if($current.Name -eq "ff000000")
{
$oceanPixels.Add(($x,$y))
}
else
{
$landPixels.Add(($x,$y))
}
}
}
P.P.S.
$x,$y = $square
P.P.P.S
if(
(($y+1 -lt $map.Height) -and ($map.GetPixel($x, ($y+1)).Name -eq "ff000000")) -or
(($y-1 -gt 0) -and ($map.GetPixel($x, ($y-1)).Name -eq "ff000000")) -or
(($x+1 -lt $map.Width) -and ($map.GetPixel(($x+1), $y).Name -eq "ff000000")) -or
(($x-1 -gt 0) -and ($map.GetPixel(($x-1), $y).Name -eq "ff000000"))
)
{
$map.SetPixel($x, $y, "lime")
}