Blending (compositing with alpha) two images with GDI+

Posted on 2004-11-10
Last Modified: 2008-02-01
PictureBox1, PictureBox2, and PictureBox3 sit on a form. All are the same size. I want to blend the images in 1 and 2 together and put the blended image into PictureBox3, with PictureBox1 on top at an alpha level of my choosing. Thanks.
Question by:rdavis101
    LVL 85

    Expert Comment

    by:Mike Tomlinson
    Public Class Form1
        Inherits System.Windows.Forms.Form

    #Region " Windows Form Designer generated code "

        Public Sub New()

            'This call is required by the Windows Form Designer.

            'Add any initialization after the InitializeComponent() call

        End Sub

        'Form overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not (components Is Nothing) Then
                End If
            End If
        End Sub

        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        Friend WithEvents PictureBox1 As System.Windows.Forms.PictureBox
        Friend WithEvents PictureBox2 As System.Windows.Forms.PictureBox
        Friend WithEvents PictureBox3 As System.Windows.Forms.PictureBox
        Friend WithEvents Button1 As System.Windows.Forms.Button
        Friend WithEvents Button2 As System.Windows.Forms.Button
        Friend WithEvents Button3 As System.Windows.Forms.Button
        Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown
        Friend WithEvents Label1 As System.Windows.Forms.Label
        Friend WithEvents OpenFileDialog1 As System.Windows.Forms.OpenFileDialog
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.PictureBox1 = New System.Windows.Forms.PictureBox
            Me.PictureBox2 = New System.Windows.Forms.PictureBox
            Me.PictureBox3 = New System.Windows.Forms.PictureBox
            Me.Button1 = New System.Windows.Forms.Button
            Me.Button2 = New System.Windows.Forms.Button
            Me.Button3 = New System.Windows.Forms.Button
            Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown
            Me.Label1 = New System.Windows.Forms.Label
            Me.OpenFileDialog1 = New System.Windows.Forms.OpenFileDialog
            CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
            Me.PictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
            Me.PictureBox1.Location = New System.Drawing.Point(8, 8)
            Me.PictureBox1.Name = "PictureBox1"
            Me.PictureBox1.Size = New System.Drawing.Size(200, 200)
            Me.PictureBox1.TabIndex = 0
            Me.PictureBox1.TabStop = False
            Me.PictureBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
            Me.PictureBox2.Location = New System.Drawing.Point(296, 8)
            Me.PictureBox2.Name = "PictureBox2"
            Me.PictureBox2.Size = New System.Drawing.Size(200, 200)
            Me.PictureBox2.TabIndex = 1
            Me.PictureBox2.TabStop = False
            Me.PictureBox3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
            Me.PictureBox3.Location = New System.Drawing.Point(168, 232)
            Me.PictureBox3.Name = "PictureBox3"
            Me.PictureBox3.Size = New System.Drawing.Size(200, 200)
            Me.PictureBox3.TabIndex = 2
            Me.PictureBox3.TabStop = False
            Me.Button1.Location = New System.Drawing.Point(216, 8)
            Me.Button1.Name = "Button1"
            Me.Button1.Size = New System.Drawing.Size(72, 32)
            Me.Button1.TabIndex = 3
            Me.Button1.Text = "Select Image"
            Me.Button2.Location = New System.Drawing.Point(504, 8)
            Me.Button2.Name = "Button2"
            Me.Button2.Size = New System.Drawing.Size(72, 32)
            Me.Button2.TabIndex = 4
            Me.Button2.Text = "Select Image"
            Me.Button3.Location = New System.Drawing.Point(392, 264)
            Me.Button3.Name = "Button3"
            Me.Button3.Size = New System.Drawing.Size(72, 32)
            Me.Button3.TabIndex = 5
            Me.Button3.Text = "Blend Images"
            Me.NumericUpDown1.Location = New System.Drawing.Point(424, 232)
            Me.NumericUpDown1.Maximum = New Decimal(New Integer() {255, 0, 0, 0})
            Me.NumericUpDown1.Name = "NumericUpDown1"
            Me.NumericUpDown1.Size = New System.Drawing.Size(48, 20)
            Me.NumericUpDown1.TabIndex = 6
            Me.NumericUpDown1.Value = New Decimal(New Integer() {128, 0, 0, 0})
            Me.Label1.Location = New System.Drawing.Point(376, 232)
            Me.Label1.Name = "Label1"
            Me.Label1.Size = New System.Drawing.Size(40, 16)
            Me.Label1.TabIndex = 7
            Me.Label1.Text = "Alpha:"
            Me.Label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight
            Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
            Me.ClientSize = New System.Drawing.Size(584, 446)
            Me.Name = "Form1"
            Me.Text = "AlphaBlend Two Images"
            CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()

        End Sub

    #End Region

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        End Sub

        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        End Sub

        Private Sub setImage(ByVal pb As PictureBox)
            OpenFileDialog1.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*"
            If OpenFileDialog1.ShowDialog = DialogResult.OK Then
                    pb.Image = Image.FromFile(OpenFileDialog1.FileName)
                Catch ex As Exception
                    MessageBox.Show(ex.Message, "Error Loading Image", MessageBoxButtons.OK, MessageBoxIcon.Error)
                End Try
            End If
        End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            Button3.Enabled = False

            Dim tempBMP As Bitmap = New Bitmap(PictureBox1.Image)
            Dim clr As Color
            Dim x As Integer
            Dim y As Integer
            For y = 0 To tempBMP.Height - 1
                For x = 0 To tempBMP.Width - 1
                    clr = tempBMP.GetPixel(x, y)
                    tempBMP.SetPixel(x, y, _
                        Color.FromArgb(NumericUpDown1.Value, clr.R, clr.G, clr.B))
                Next x
            Next y

            Dim temp2BMP As Bitmap = New Bitmap(PictureBox2.Image)
            Dim gr As Graphics = Graphics.FromImage(temp2BMP)
            gr.DrawImage(tempBMP, 0, 0)
            PictureBox3.Image = temp2BMP

            Button3.Enabled = True
        End Sub

    End Class

    Author Comment

    Thanks...this is a great example project. I was wondering if there's a way of using compositing to set the alpha for the entire image, rather than by doing it by pixel, which could slow down on larger images?

    LVL 85

    Expert Comment

    by:Mike Tomlinson
    It is a pretty slow operation and I'm not sure if there is a way to do it without going pixel by pixel.  Unfortunately, I'm not a graphics wizard so that's the best solution I can  give you...  =\

    It would probably run much faster using unmanaged C code with direct access to the API's but I can't help you there.

    Hopefully some EE graphics gurus will pipe in and educate us both.  =)


    Author Comment

    Okay...had some time to check this out... Just add another button to the form you suggested. This blends images using the color matrix...change the .2 in the matrix below to be whatever you want...this value controls the alpha...seems to range from 0 to 1, but I'm not sure yet. Anyway, this approach does blend whole images at a time.


       Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
            PictureBox3.Image = New Bitmap(PictureBox3.Width, PictureBox3.Height)
            Dim G As Graphics = Graphics.FromImage(PictureBox3.Image)

            Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
                   {New Single() {1, 0, 0, 0, 0}, _
                    New Single() {0, 1, 0, 0, 0}, _
                    New Single() {0, 0, 1, 0, 0}, _
                    New Single() {0, 0, 0, 0.2, 0}, _
                    New Single() {0, 0, 0, 0, 1}})

            Dim IA As New ImageAttributes

            IA.SetColorMatrix(CM, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)
            G.DrawImage(PictureBox1.Image, 0, 0)
            G.DrawImage(PictureBox2.Image, PictureBox3.ClientRectangle, 0, 0, PictureBox3.Width, PictureBox3.Height, GraphicsUnit.Pixel, IA)

        End Sub
    LVL 85

    Expert Comment

    by:Mike Tomlinson
    Well that certainly is alot faster than going pixel by pixel.  =)

    Thanx for posting it.  I'm still trying to figure out how it works.  Darned documentation...

    You can post a request in the Support TA to PAQ the question and refund your points since you answered your own question.


    Accepted Solution

    Question PAQ'd
    125 points refunded.

    Community Support Moderator

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    6 Surprising Benefits of Threat Intelligence

    All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

    Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
    Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
    Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
    This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor ( If you're looking for how to monitor bandwidth using netflow or packet s…

    759 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    10 Experts available now in Live!

    Get 1:1 Help Now