question

AndyDeFilippo-2349 avatar image
0 Votes"
AndyDeFilippo-2349 asked AndyDeFilippo-2349 answered

GDI Leak when rendering alpha-blend contents to some printers in Windows 10

I'm experiencing a very odd legacy gdi object leak when printing on certain printers under Windows 10.

It happens even when you print on Microsoft virtual printers, such as the "Microsoft XPS Document Writer".
It has to do with rendering 32bppARGB images to a printer Graphics, regardless of its origin. It happens when you render an in-memory created bitmap with argb contents.

The memory leak happens on Windows 10 19042.867 x64 and does not happen on Windows 7 (x64, x32), with the same virtual printer.
It does not happen when the contents of the image being rendered do not contain any semi-transparent pixels.

I've created a test project to easily reproduce the behavior:

 Imports System.Drawing
 Imports System.Drawing.Printing
    
 Module Module1
    
     Sub Main()
    
         ' Get Microsoft XPS Document Writer printer settings
         Dim prnSettings As New PrinterSettings() With {.PrinterName = "Microsoft XPS Document Writer"}
    
         ' Ensure printer is valid
         If prnSettings.IsValid = False Then
             MsgBox("Can't find Microsoft XPS Document Writer.", MsgBoxStyle.Exclamation)
             Exit Sub
         End If
    
         ' Init document settings
         m_prtDoc = New PrintDocument With {.DocumentName = "PNG24 print test",
                                            .PrinterSettings = prnSettings}
    
         ' Start printing
         m_prtDoc.Print()
    
         ' Clean up
         m_prtDoc.Dispose()
    
         MsgBox("Check GDI objects count, probably thru the roof.", MsgBoxStyle.Information)
    
     End Sub
    
     ' Document settings
     Private WithEvents m_prtDoc As PrintDocument = Nothing
    
     ' Page count
     Private m_iPageCount As Integer = 0
    
     Private Sub PrintPage(sender As Object, e As PrintPageEventArgs) Handles m_prtDoc.PrintPage
    
         Try
    
             ' Create in memory image of the same size
             Using imgMemory As New Bitmap(600, 400)
    
                 ' Fill with alpha color
                 Using gphMemory As Graphics = Graphics.FromImage(imgMemory)
                     gphMemory.Clear(Color.FromArgb(128, 255, 0, 0)) ' Red at 0.5 alpha
                 End Using
    
                 ' Draw in-memory image
                 e.Graphics.DrawImageUnscaled(imgMemory, e.PageBounds.Location)
    
             End Using
    
             ' Increase page counter
             m_iPageCount += 1
    
             ' The number of rendering repetitions
             Const REPETITIONS As Integer = 20
    
             ' Print up to REPETITIONS pages
             e.HasMorePages = (m_iPageCount < REPETITIONS)
    
         Catch ex As Exception
             ' Error, Stop printing
             MsgBox(ex.Message, MsgBoxStyle.Critical)
         End Try
    
     End Sub
 End Module

Stack overflow question:
https://stackoverflow.com/questions/66872343/gdi-memory-leak-when-printing-png24-images-with-gdiplus

Any help is appreciated.
Thank you.

dotnet-csharpdotnet-visual-basic
· 8
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I could reproduce it on Windows 10 1909

I tried to replace the line
gphMemory.Clear(Color.FromArgb(128, 255, 0, 0))
by equivalent
GdipGraphicsClear (from .Net source) but I could not set Alpha to compare...

1 Vote 1 ·

You can draw anything that has alpha pixels in it and the leak will appear.
Thx.

0 Votes 0 ·

Yes, weird.
I tested the ~same code in C++ : same problem with ARGB

0 Votes 0 ·
Show more comments

1 Answer

AndyDeFilippo-2349 avatar image
1 Vote"
AndyDeFilippo-2349 answered

For anyone stumbling upon this issue, it seems that the problem was solved with update KB5001649

Make sure you and/or your customers keep Windows up to date and this issue won't affect your projects.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.