VB.NET使用大量内存打印图像

时间:2012-06-18 17:29:59

标签: vb.net pdf printing

我正在使用我在代码项目中找到的DLL在VB.NET中使用PDF:

http://www.codeproject.com/Articles/37458/PDF-Viewer-Control-Without-Acrobat-Reader-Installe

我的应用程序允许您选择网格中的多个文件并打印它们。这些文件存储在受密码保护的zip文件中,因此我要做的第一步是将每个选定的文件解压缩到我传递给新的PDF包装器对象的内存流中。每个对象都被添加到队列中。然后,队列中的每个对象逐页打印,作为system.drawing.image。整个事情都在背景工作者身上运行。

现在,将PDF提取到队列几乎不使用任何内存。但是在PrintPage事件处理程序中,当我提取图像并将它们发送到打印机时,必然会出现问题。我的内存使用量爆炸了。当然,每个图像都很大,因为它以300 dpi的速度渲染,但每个页面使用的内存不会返回到操作系统,也不会被垃圾回收。

最后,如果我选择了足够的文件,我的内存不足。为什么呢?

1 个答案:

答案 0 :(得分:1)

好的,所以我终于明白了。

首先,就图像而言,CLR显然不知道为Drawing.Image分配了多少内存,所以当你处理它时,你必须告诉它:

'It's 4 bytes per pixel with RGBA
'Use Drawing.Image.PixelFormat to get
'the number of bytes if you don't know
Dim countBytes as long = 4 * img.Width * img.Height

'Let the CLR know of the memory we want to free
if countBytes > 0 then GC.AddMemoryPressure(countBytes)

'Get rid of the image
img.Dispose()
img = Nothing

'Free up the unused memory
GC.Collect()

'Tell the CLR we took care of it
GC.RemoveMemoryPressure(countBytes)

现在,CodeProject示例中的PDF库非常困难。

首先,确保在包含包装器的表单的Dispose事件或PDFWrapper中的FormClosed对象上调用Finalize方法包含它的类的方法。

但是,PDFWrapper实际上似乎缓存了从中检索的图像。因此,当您翻阅PDF时,内存使用量将会增长,直到缓存整个PDF的图像为止。如果您使用这些图像以300DPI打印PDF,那么这是一个更大的问题(在使用1.5GB内存的情况下,我会在60页以上的PDF结尾处出现内存错误。)

据我所知,这个对象没有'Clear Cache'方法。但是我以前使用它的黑客工作是在获得我需要的图像后以1DPI获取图像,然后执行如上所述的垃圾收集。这间接释放了缓存的内存。但是,和以前一样,我们必须告诉CLR我们使用了多少字节。它与上面的计算方法相同。

但还有一个问题。看起来,PDFWrapper对象实际上抓住了另一个线程上的图像。因此,通过在我们请求300DPI图像之后请求另一个1DPI图像,当它应该给我们打印300DPI图像时,它会混淆并随机吐出1DPI图像。所以,解决方法是:

Dim img As System.Drawing.Image
img = AFPDFLibUtil.GetImageFromPDF(pdfWrapper, currentPage, DPI)

'Wait for PDFWrapper to finish rendering
Dim sw As New Stopwatch()
sw.Start()
While _pdfWrapper.IsBusy
    If sw.ElapsedMilliseconds < TimeoutMS Then
        System.Threading.Thread.Sleep(10)
    Else
        Throw New Exception("This page took too long to render.")
    End If
End While
sw.Stop()
sw.Reset()

你去吧。也许这就是为什么在CodeProject示例中,他使用不同的DLL来进行打印。但是,PDFWrapper对象支持从IO.MemoryStream读取,我不认为该项目中的任何其他内容都包括在内。

任何阅读此内容的人都可以快乐编码!