You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GDI+打印PNG24图像时出现GDI对象内存泄漏问题求助

GDI Object Leak When Printing 32bppARGB Bitmaps to Windows 10 Printers (Including Microsoft XPS Document Writer)

I'm hitting a strange persistent GDI object leak on Windows 10 when printing to certain printers—even the Microsoft XPS Document Writer virtual printer exhibits this issue. The leak only seems to occur when working with PNG24 images (or more broadly, 32bppARGB bitmaps), and I've created test projects to reproduce the behavior consistently.

Reproduction Scenario 1: Using a PNG24 Image

This code loads a PNG24 file, copies it to an in-memory bitmap, then renders that bitmap to the printer's graphics context. After repeated prints, GDI object count spikes dramatically:

Imports System.Drawing
Imports System.Drawing.Printing

Module Module1
    ' The PNG 24 source image
    Private Const SOURCE_PNG24_FILE As String = "[Path to any png 24 image]"
    ' The number of rendering repetitions
    Private Const REPETITIONS As Integer = 100

    Sub Main()
        MsgBox("Open the task manager and check GDI objects count for this application, should be around 15.", MsgBoxStyle.Information)
        ' 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()
        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
            ' Load png 24 image
            Using imgSourcePng24 As Image = Image.FromFile(SOURCE_PNG24_FILE)
                ' Create in memory image of the same size
                Using imgMemory As New Bitmap(imgSourcePng24.Width, imgSourcePng24.Height)
                    ' Get the in-memory graphics
                    Using gphMemory As Graphics = Graphics.FromImage(imgMemory)
                        ' Draw source image
                        gphMemory.DrawImage(imgSourcePng24, New Rectangle(Point.Empty, imgSourcePng24.Size), New Rectangle(Point.Empty, imgSourcePng24.Size), GraphicsUnit.Pixel)
                    End Using
                    ' Draw in-memory image -> Comment this line and no GDI object spike
                    e.Graphics.DrawImage(imgMemory, New Rectangle(Point.Empty, imgMemory.Size), New Rectangle(Point.Empty, imgMemory.Size), GraphicsUnit.Pixel)
                End Using
            End Using
            ' Increase page count
            m_iPageCount += 1
            ' 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

Key Observations from Initial Testing

  • The leak occurs on Windows 10 19042.867, but does NOT occur on Windows 7 with the same Microsoft XPS Document Writer.
  • No leak happens when rendering PNG8 or JPG images, or when drawing the PNG24 directly to the printer's Graphics object (skipping the in-memory bitmap step).
  • I've also seen this leak in a Win32 project, leading me to suspect it's related to the GdipCreateBitmapFromScan0 function called under the hood when creating empty bitmaps.

Reproduction Scenario 2: In-Memory 32bppARGB Bitmap

Further testing revealed the leak isn't limited to loaded PNGs—it happens whenever a 32bppARGB bitmap (with alpha channel content) is rendered to the printer's Graphics context:

Private Sub PrintPage(sender As Object, e As PrintPageEventArgs) Handles m_prtDoc.PrintPage
    Try
        ' Create in memory image
        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

I'm stuck on figuring out a workaround or root cause here—any help or insights would be greatly appreciated!


内容的提问来源于stack exchange,提问作者AndyDF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:12:35