Process Block Not Work in Graphics.DrawString

2019-04-12 21:36发布

问题:

I have a PowerShell function (out()). When I want to get a result from pipeline into an image, it takes the last object from the pipeline. For example: I want to show all objects in (gps):

function out {
[cmdletbinding()]
param(
    [parameter(
        Mandatory = $true,
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true)]
    [string[]]
    $n
)



    Process {
    $dirname = Get-Location | Select-Object -ExpandProperty Path
    $filename = $(Get-Date -f "yyyy-mm-dd--hh-mm-ss-tt") + "--image.png"
    $ImagePath = $dirname + "\" + $filename

      ForEach ($input in $n) {

        #PUT Your Image:
         $basefilename = "D:\ZalansDB\imgs\main\bg_D.jpg"
            $bmp = [System.Drawing.Bitmap]::FromFile("$basefilename")

            $font = new-object System.Drawing.Font ('Microsoft Sans Serif',16)
            $fcolors = [System.Drawing.Brushes]
            $graphics = [System.Drawing.Graphics]::FromImage($bmp)

            $graphics.DrawString($input,$font,$fcolors::White,30,40)


            $filename = $ImagePath
            $graphics.Dispose() 
            $bmp.Save($filename)
         } 




            Invoke-Item $filename 


    } 



}

Get-Process | Select-Object -First 2 | out

Result:

I want to show First 2 prcoess objects into my image

回答1:

I could see loads of valid approaches for this. Use begin block to set the variables that are not going to change. Use the process block to collect the process names. Finally, use end to display the image. We use -join to get them all in one string so we don't have to redraw, and manage locations, all the time.

function Set-ProcessPicture{
    [cmdletbinding()]
    param(
        [parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true)]
        [Alias("ProcessName")]
        $Process,
        [parameter(Mandatory=$false)]
        $BaseImagePath = "d:\temp\test.jpg"
    )


    begin{
        $dirname = Get-Location | Select-Object -ExpandProperty Path
        $font = new-object System.Drawing.Font ('Microsoft Sans Serif',16)
        $fcolors = [System.Drawing.Brushes]
        $baseBitmap = [System.Drawing.Bitmap]::FromFile($BaseImagePath)
        $graphics = [System.Drawing.Graphics]::FromImage($baseBitmap)

        $outputString = @()
    }

    Process {
        $outputString += $process
    } 
    end {
        $graphics.DrawString(($outputString -join "`r`n"),$font,$fcolors::White,30,40)
        $filename = [io.path]::Combine((Get-Location).Path,(Get-Date -f "yyyy-MM-dd--hh-mm-ss-fff") + "--image.png")
        $graphics.Dispose() 
        $baseBitmap.Save($filename)

        Invoke-Item $filename 
    }

}

Get-Process | Select-Object -First 2 | Set-ProcessPicture

I made a few best practice code changes. This is not how I would leave it but corrects the issue that you were having.

Note: Use MM for months in your format strings