VB.Net BufferedGraphics transparent background
graphics, vb.net
Solution
The buffer you get from BufferedGraphics is not useful, it has the wrong pixel format. You want to create your own buffer, one that can support transparency. Which requires a 32bpp format. Make it Format32bppPArgb to make it as fast as possible. Rewriting this code with some additional support for resizing the form and all flicker eliminated:
Public Class Form1
Private backBuffer As Bitmap
Public Sub New()
InitializeComponent()
Me.DoubleBuffered = True
Me.ResizeRedraw = True
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
Dim newBuffer = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
If backBuffer IsNot Nothing Then
Using gr As Graphics = Graphics.FromImage(newBuffer)
gr.DrawImage(backBuffer, Point.Empty)
End Using
backBuffer.Dispose()
End If
backBuffer = newBuffer
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseMove(e)
If e.Button = Windows.Forms.MouseButtons.Left Then
Using gr As Graphics = Graphics.FromImage(backBuffer)
gr.FillEllipse(New SolidBrush(Color.Blue), CInt(e.X - (100 / 2)), CInt(e.Y - (100 / 2)), 100, 100)
End Using
Me.Invalidate()
End If
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
e.Graphics.DrawImage(backBuffer, Point.Empty)
MyBase.OnPaint(e)
End Sub
End Class
Problem
I am using BufferedGraphics to draw some stuff and then I draw it on to a user control. This is the code: ``` Private context As BufferedGraphicsContext Private grafx As BufferedGraphics Private Sub PaintDoc_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True) Me.UpdateStyles() context = BufferedGraphicsManager.Current context.MaximumBuffer = New Size(Me.Width + 1, Me.Height + 1) grafx = context.Allocate(Me.CreateGraphics, New Rectangle(0, 0, Me.Width, Me.Height)) grafx.Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear grafx.Graphics.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality grafx.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality grafx.Graphics.Clear(Color.Transparent) End Sub Private Sub PaintDoc_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove If e.Button = Windows.Forms.MouseButtons.Left Then grafx.Graphics.FillEllipse(New SolidBrush(DrawColorFinal), CInt(e.x - (BrushWidth / 2)), CInt(e.y - (BrushWidth / 2)), BrushWidth, BrushWidth) Me.Invalidate() End If End Sub Private Sub PaintDoc_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint grafx.Render(e.Graphics) End Sub ``` The problem is that the grafx doesn't have a transparent background as it sould, but a black background. Any ideas why? UPDATE: Thanks to Hans Passant the problem solved and here is the final code that also supports a fast multilayer image drawing: ``` Public Class PaintDoc Public backBuffer(1) As Bitmap Public bufferGraphics(1) As Graphics Public layerIndex As Integer = 0 Private Sub PaintDoc_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Me.SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint, True) Me.UpdateStyles() For i As Integer = 0 To backBuffer.Length - 1 backBuffer(i) = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb) bufferGraphics(i) = Graphics.FromImage(backBuffer(i)) bufferGraphics(i).InterpolationMode = Drawing2D.InterpolationMode.HighQualityBilinear bufferGraphics(i).PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality bufferGraphics(i).SmoothingMode = Drawing2D.SmoothingMode.HighQuality Next End Sub Private Sub PaintDoc_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove If e.Button = Windows.Forms.MouseButtons.Left Then bufferGraphics(layerIndex).FillEllipse(New SolidBrush(DrawColorFinal), CInt(e.X - (BrushWidth / 2)), CInt(e.Y - (BrushWidth / 2)), BrushWidth, BrushWidth) Me.Invalidate() End If End Sub Private Sub PaintDoc_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint e.Graphics.Clear(Color.Transparent) For i As Integer = 0 To backBuffer.Length - 1 e.Graphics.DrawImage(backBuffer(i), Point.Empty) Next End Sub Private Sub PaintDoc_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize For i As Integer = 0 To backBuffer.Length - 1 Dim newBuffer As Bitmap = New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb) If backBuffer(i) IsNot Nothing Then Using gr As Graphics = Graphics.FromImage(newBuffer) gr.DrawImage(backBuffer(i), Point.Empty) End Using backBuffer(i) = Nothing End If backBuffer(i) = newBuffer Next End Sub End Class ```