You want to blend two images together, with a variable strength for each, to create a ghost-like effect.
Sample code folder: Chapter 10\MergeImages
Use the GetPixel() method of the Bitmap class to process the pixels from matching locations in each of the original images, and use the SetPixel() method to assign the resulting pixels to a third bitmap to create the merged image.
This recipe processes the pixels from two identically sized images and creates a third. The action is slow enough that intermediate results are displayed after each row of pixels is processed. To try it out, add the following code to the form's class. The code loads two image files (in Form1_Load()) and does the actual processing (DoMergeImages()):
Private SourceImages(1) As Bitmap Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' ----- Prepare the form. Dim counter As Integer Dim locateFile As New OpenFileDialog ' ----- Display the form immediately. Me.Show( ) ' ----- Prompt for each file. locateFile.Filter = "JPG files (*.jpg)|*.jpg" For counter = 0 To 1 ' ----- Prompt for the initial file. If (locateFile.ShowDialog( ) <> _ Windows.Forms.DialogResult.OK) Then ' ----- End the program. Me.Close( ) Return End If ' ----- Load in the picture. SourceImages(counter) = New Bitmap(locateFile.FileName) Next counter ' ----- Start the processing. DoMergeImages( ) End Sub Private Sub Form1_FormClosed(ByVal sender As Object, _ ByVal e As System.Windows.Forms.FormClosedEventArgs) _ Handles Me.FormClosed ' ----- Exit the program. This is needed just in case the ' user closed the form in the middle of the merge. End End Sub Private Sub DoMergeImages( ) ' ----- Merge two images. Dim workBitmap As Bitmap Dim across As Integer Dim down As Integer Dim firstColor As Color Dim secondColor As Color Dim mixedColor As Color Dim redPart As Integer Dim greenPart As Integer Dim bluePart As Integer Dim canvas As Graphics ' ----- Use one of the images as the base. workBitmap = SourceImages(0) canvas = Graphics.FromImage(workBitmap) ' ----- Process each row of the image. For down = 0 To SourceImages(0).Height - 1 ' ----- Process each column of the image. For across = 0 To SourceImages(0).Width - 1 Try ' ----- Get the colors of a specific pixel. firstColor = _ SourceImages(0).GetPixel(across, down) secondColor = _ SourceImages(1).GetPixel(across, down) Catch ' ----- If an error occurs, the images must have ' been mismatched in size. Continue For End Try ' ----- Build a blended color from the parts. redPart = (CInt(firstColor.R) + secondColor.R) \ 2 greenPart = (CInt(firstColor.G) + secondColor.G) \ 2 bluePart = (CInt(firstColor.B) + secondColor.B) \ 2 mixedColor = Color.FromArgb(redPart, greenPart, _ bluePart) ' ----- Update the image. workBitmap.SetPixel(across, down, mixedColor) Next across ' ----- Refresh the display so the user knows ' something is happening. MergedImage.Image = workBitmap Application.DoEvents( ) Next down canvas.Dispose( ) End Sub
Figure 10-20 shows the results of blending together images of a goose and the Grand Teton mountains. The code blends the pixels equally by adding together the color values and dividing by two to find their averages. You could easily modify this averaging to place more weight on the pixels from one image or the other. Another creative experiment might be to average together only one or more of the color channels (red, green, or blue).
Figure 10-20. Blending two pictures for a ghostly effect