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.
Comments