Click here to Skip to main content
Licence 
First Posted 11 Feb 2002
Views 330,665
Bookmarked 157 times

Per Pixel Alpha Blend in C#

By | 3 Jun 2004 | Article
Demonstrates how to create per pixel alpha blending windows

Preview of the per pixel alpha blend effect

Preview of the per pixel alpha blend effect

Introduction

This is a port of my other article from C++/MFC to C#/Windows Forms. The concept of creating a per-pixel-alpha blending window remains the same, the GDI function UpdateLayeredWindow.

What changed

  • Image loading is handled by GDI+ classes (System.Drawing namespace).
  • No need to pre-multiply the rgb channels with the alpha channel.
  • No more support for PSP files. PNG file are the best choice.

Usage

To use this code you need to include PerPixelAlphaForm.cs file in your project, create a class that inherits from PerPixelAlphaForm, load a bitmap using System.DrawingImage.FromFile static method and then call the PerPixelAlphaForm.SetBitmap method.

The example source code is inside the main.cs file. In the source code you will also find the new ways of doing the old things, like, handling dropped files from windows explorer.

Installing & Building

  1. Download and extract the source code of this article;
  2. To build, run the build.bat file from command prompt;
  3. Now, run the bin\main.exe and enjoy!

Changelog

31 May 2004

  • Fix clipping problems by creating the form without borders.
  • Move PerPixelAlphaForm class to PerPixelAlphaForm.cs file.

12 Feb 2002

  • Initial version.

Do you have any question or comment? Contact me!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rui Lopes

Web Developer

Portugal Portugal

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionGreat but can I use the function also for a control? Pinmemberit-bergmann1:24 14 Feb '08  
AnswerRe: Great but can I use the function also for a control? PinmemberMember 42028004:49 19 May '09  
Generalcool Pinmemberradioman.lt@gmail.com22:20 12 Dec '07  
Questionwhy doing win32 with c#? Pinmemberbkaratte20:46 11 Dec '07  
AnswerRe: why doing win32 with c#? Pinmembertic8413:12 10 Jun '08  
GeneralVB.Net Pinmemberdawmail33322:47 24 Aug '07  
GeneralRe: VB.Net PinmemberDj Den4ik23:05 11 Feb '08  
Class:

Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
'Translation from C# by Dj Den4ik
Public Class PerPixelAlphaForm
'Implements Windows.Forms.IWin32Window
 
Public Structure ARGB
Public Blue As Byte
Public Green As Byte
Public Red As Byte
Public Alpha As Byte
End Structure
 
Public Structure BLENDFUNCTION
Public BlendOp As Byte
Public BlendFlags As Byte
Public SourceConstantAlpha As Byte
Public AlphaFormat As Byte
End Structure
 
Public Const ULW_COLORKEY As Int32 = &H1
Public Const ULW_ALPHA As Int32 = &H2
Public Const ULW_OPAQUE As Int32 = &H4
 
Public Const AC_SRC_OVER As Byte = &H0
Public Const AC_SRC_ALPHA As Byte = &H1
 
Public Declare Function UpdateLayeredWindow Lib "user32" Alias "UpdateLayeredWindow" (ByVal hwnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As Point, ByRef psize As Size, ByVal hdcSrc As IntPtr, ByRef pprSrc As Point, ByVal crKey As Int32, ByRef pblend As BLENDFUNCTION, ByVal dwFlags As Int32) As Boolean
Public Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hWnd As IntPtr) As IntPtr
Public Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
Public Declare Function CreateCompatibleDC Lib "gdi32.dll" Alias "CreateCompatibleDC" (ByVal hDC As IntPtr) As IntPtr
Public Declare Function DeleteDC Lib "gdi32.dll" Alias "DeleteDC" (ByVal hDC As IntPtr) As Boolean
Public Declare Function SelectObject Lib "gdi32.dll" Alias "SelectObject" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
Public Declare Function DeleteObject Lib "gdi32.dll" Alias "DeleteObject" (ByVal hObject As IntPtr) As Boolean
 
Public Sub SetBitmap(ByVal bitmap As Bitmap, ByVal opacity As Byte, ByVal frm As Form)
If bitmap.PixelFormat <> PixelFormat.Format32bppArgb Then Throw New ApplicationException("The bitmap must be 32ppp with alpha-channel.")
 
' The ideia of this is very simple,
' 1. Create a compatible DC with screen;
' 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
' 3. Call the UpdateLayeredWindow.
 
Dim screenDc As IntPtr = GetDC(IntPtr.Zero)
Dim memDc As IntPtr = CreateCompatibleDC(screenDc)
Dim hBitmap As IntPtr = IntPtr.Zero
Dim oldBitmap As IntPtr = IntPtr.Zero
 
Try
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)) ' grab a GDI handle from this GDI+ bitmap
oldBitmap = SelectObject(memDc, hBitmap)
Dim size As New Size(bitmap.Width, bitmap.Height)
Dim pointSource As New Point(0, 0)
Dim topPos As New Point(frm.Left, frm.Top)
Dim blend As New BLENDFUNCTION
blend.BlendOp = AC_SRC_OVER
blend.BlendFlags = 0
blend.SourceConstantAlpha = opacity
blend.AlphaFormat = AC_SRC_ALPHA
UpdateLayeredWindow(frm.Handle, screenDc, topPos, size, memDc, pointSource, 0, blend, ULW_ALPHA)
Finally
ReleaseDC(IntPtr.Zero, screenDc)
If hBitmap <> IntPtr.Zero Then
SelectObject(memDc, oldBitmap)
DeleteObject(hBitmap)
End If
DeleteDC(memDc)
 
End Try
End Sub

 
Form:

Dim ppaf As New PerPixelAlphaForm
Dim bmp As New Bitmap("D:\Audio\FL Studio 7\Artwork\FL Studio Producer Edition\Title_.png")
 
Protected Overrides ReadOnly Property CreateParams() As System.Windows.Forms.CreateParams
Get
Dim SecPerm As New Security.Permissions.SecurityPermission(Security.Permissions.PermissionState.Unrestricted)
SecPerm.Demand()
 
' Extend the CreateParams property of the Button class.
Dim cp As System.Windows.Forms.CreateParams = MyBase.CreateParams
' Update the button Style.
cp.ExStyle = &H80000
 
Return cp
End Get
End Property
 
Private Sub frmTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.TopMost = True
For Each ctrl As Control In Me.Controls
ctrl.DrawToBitmap(bmp, ctrl.Bounds)
Next
Me.Region = New Region()
ppaf.SetBitmap(bmp, 240, Me)
End Sub
 

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
 
Const WM_MOUSEMOVE As Int32 = &H200
Const WM_NCLBUTTONDOWN As Int32 = &HA1
Const HTCAPTION As Int32 = 2
 
'// ????????????? WM_MOUSEMOVE
If m.Msg = WM_MOUSEMOVE Then
 
'// ???????? ReleaseCapture
MyBase.Capture = False
 
'// ??????? ???? ?????????
Dim message As New Message
With message
.HWnd = Me.Handle
.Msg = WM_NCLBUTTONDOWN
.WParam = HTCAPTION
.LParam = 0&
End With
 
'// ?????????? ???? ????????? ????
MyBase.WndProc(message)
End If
 
MyBase.WndProc(m)
 
End Sub

Smile | :)
GeneralRe: VB.Net PinmemberJason Newland19:31 25 Apr '12  
GeneralRe: VB.Net PinmemberJason Newland19:33 25 Apr '12  
GeneralGreat!!!!!!!!!!!!! Pinmembershp-coding7:44 9 Aug '07  
GeneralWay to add some controls Pinmemberihess4:17 30 Jul '07  
GeneralRe: Way to add some controls [modified] PinmemberSp3cial8:12 24 Aug '08  
GeneralRe: Way to add some controls [modified] PinmemberLatencyXXX23:21 23 Jan '11  
GeneralHelp Pinmembergsampath20:15 28 May '07  
GeneralImage problem Pinmemberdarb212:57 20 Apr '07  
GeneralRe: Image problem PinmemberDaryl Fish14:58 15 Jan '08  
GeneralProblem when changing the form parent to desktop with dual-monitoring [modified] PinmemberPim-Pom1:59 7 Oct '06  
GeneralNice example, but... Pinmembermoebiusproject9:35 12 Sep '06  
GeneralRe: Nice example, but... PinmemberTung Nguyen17:37 15 Apr '07  
GeneralRe: Nice example, but... Pinmembertic8413:14 10 Jun '08  
GeneralProblem in design mode PinmemberCapt'N Stabbin'19:09 12 Jul '06  
GeneralRe: Problem in design mode PinmemberODaniell0:52 3 Aug '06  
GeneralRe: Problem in design mode PinmemberMember 42028004:50 19 May '09  
QuestionHow Can I Add Controls? Pinmemberranzige16:32 2 Dec '05  
AnswerRe: How Can I Add Controls? Pinmemberwang.songqing20:16 20 Jun '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 4 Jun 2004
Article Copyright 2002 by Rui Lopes
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid