Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Friday, January 29, 2016

How to copy a Portion of an Image and Paste it into a Section of a PictureBox Control vwith PowerShell

This one has been a thorn in my side for a long time.  As a matter of fact, it has stopped several projects while I figure it out.  We are all familiar with the concept of selecting part of an image and then pasting that selection where we want.  The problem that I have been facing is how to do that in code with PowerShell.

I’m utilizing SAPIEN PowerShell Studio 2015 for a project involving images.  I need to take parts of multiple images and assemble them into a single PictureBox control.  Even my most beloved search engine was not helping me much. Let’s start off with making a copy of part of an image.
To set this up I created a form with 3 PictureBox controls.


The red box is P1, the green is P2, and the blue is P3.  I colorized them so we can see what is going on in each as we progress through the code. Each PictureBox is 256, 256 in size.

# Load the image into P1
$P1.ImageLocation = "E:\PowerShell\InDev\Graphics1\a-0320.jpg"
$P1.Load()




Next we will create a bitmap in memory and store the image from P1 into it.

# Create a new empty bitmap in memory and store the contents of P1.
$BMP0 = [System.Drawing.Bitmap]::New($P1.Image)

We need to create a System.Drawing.Rectangle structure and give it the initial location and the height and width.  Here is the link to MSDN to describe this object: https://msdn.microsoft.com/en-us/library/system.drawing.rectangle(v=vs.110).aspx

# Create a rectangle representing to portion of the image to capture
$SourceRec = [System.Drawing.Rectangle]::New(51, 101, 100, 100)

The first two numbers are the x and y coordinates of where the upper left of the rectangle will be.  Remember, (0, 0) is in the upper left.  The third number is the number of pixels in width and the fourth is the number of pixels in height.  This rectangle will be used to capture an area of the image that starts at (51, 101) and is both 100 pixels wide and high.  The lower right hand corner of this rectangle will be at location (151, 201).

Now paste the copied image into P2.

# Paste this image into P2.
$P2.Image = $BMP0.clone($SourceRec, $BMP0.PixelFormat)


By default, the image is pasted into the upper left corner of the image.  Our next task is to paste this image anywhere we want.

We need to create another image object in memory.  This time make it the size of the PictureBox P3.

# Create a new bitmap to hold the new image.
$BMP1 = [System.Drawing.Bitmap]::New(256, 256)

Next create another rectangle structure.  This time the first two values are the upper left corner of the rectangle in the new image where you want to paste.  In this case, (10, 40).  The rectangle will be 100 x 100 in size. This is the same size as the captured image.

# Create a rectangle to represent the area to paste the image.
$DestRec = [System.Drawing.Rectangle]::New(10, 40, 100, 100)

Using P2 as our source image, we are going to draw it into $BMP1.  Notice that we use the $DestRec structure to specify where to draw it in the image.

# Draw the contents of $P2 to the location specified in $DestRec.
$P2.DrawToBitmap($BMP1, $DestRec)

Next we draw the image $BMP1 into PictureBox P3. 

# Display the image $BMP1 in P3.
$P3.Image = $BMP1



You can call the Dispose method on $BMP0 since we are not using it, but you cannot call Dispose on $BMP1 since it is being referenced as the image for $P3.

Here is the full code that is inserted into the $Form1_Load event.

# Load the image into P1
$P1.ImageLocation = "E:\PowerShell\InDev\Graphics1\a-0320.jpg"
$P1.Load()
      
# Create a new empty bitmap in memory and store the contents of P1.
$BMP0 = [System.Drawing.Bitmap]::New($P1.Image)
      
# Create a rectangle representing to portion of the image to capture
$SourceRec = [System.Drawing.Rectangle]::New(51, 101, 100, 100)
      
# Paste this image into P2.
$P2.Image = $BMP0.clone($SourceRec, $BMP0.PixelFormat)
      
# Create a new bitmap to hold the new image.
$BMP1 = [System.Drawing.Bitmap]::New(256, 256)
      
# Create a rectangle to represent the area to paste the image.
$DestRec = [System.Drawing.Rectangle]::New(10, 40, 100, 100)
             
# Draw the contents of $P2 to the location specified in $DestRec.
$P2.DrawToBitmap($BMP1, $DestRec)
      
# Display the image $BMP1 in P3.
$P3.Image = $BMP1

 You can set the Visible property on P1 and P2 to $False if you want to hide them and only display the final image.


As we continue to watch PowerShell evolve, you will be tasked to come up with more user friendly ways for our non-technical users to take advantage of PowerShell.  This should help in the creation of effective GUIs for the end user. 

No comments: