VB.Net Transparent Background BufferedGraphics

I use BufferedGraphics to draw some things and then draw them on 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(ex - (BrushWidth / 2)), CInt(ey - (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 grafx does not have a transparent background, as it were, but on a black background. Any ideas why?

UPDATE:

Thanks to Hans Passant, the problem is resolved, and here is the final code that also supports fast multi-layer 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(eX - (BrushWidth / 2)), CInt(eY - (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 
+4
source share
1 answer

The buffer you get from BufferedGraphics is not useful, it has the wrong pixel format. You want to create your own buffer that can support transparency. This requires 32bpp format. Make it Format32bppPArgb to make it as fast as possible. Rewriting this code with some additional support to resize the form and eliminate all flickering:

 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(eX - (100 / 2)), CInt(eY - (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 
+6
source

Source: https://habr.com/ru/post/1439163/


All Articles