Skip to main content

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

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.