pvginkel / PdfiumViewer

PDF viewer based on Google's PDFium.
Apache License 2.0
967 stars 418 forks source link

Unhandled exception when Render page #93

Closed Jodanas closed 7 years ago

Jodanas commented 7 years ago

Hey. Sorry for bad english :) When you try to obtain images for a plurality of files, the library may suddenly shut down, throwing out of the program without showing any error. Add a reference to the assembly. specify a list of files, units 500 and starts processing. To play you need to run a cycle, in which the extracted image of the page for each PDF file. Sometimes processed 10, sometimes 34 pieces, that is, each time his; the list does not change the files. `Dim flist As New List(Of String) flist.AddRange(Directory.GetFiles("x:\", ".pdf", SearchOption.AllDirectories).ToList) flist.AddRange(Directory.GetFiles("z:\", ".pdf", SearchOption.AllDirectories).ToList) For Each ff In flist.Where(Function(x) System.IO.Path.GetFileNameWithoutExtension(x).StartsWith(".") = False) File.AppendAllText("C:\fx\xrenderLog.txt", ff & vbCrLf) Try Using doc As PdfiumViewer.PdfDocument = PdfiumViewer.PdfDocument.Load(ff)

                Dim ts = Now
                For n = 0 To doc.PageCount
                    Dim img = doc.Render(n, 90, 110, 72, 72, PdfiumViewer.PdfRenderFlags.None)
                    img.Save("C:\fx\very\" & n & ".png", System.Drawing.Imaging.ImageFormat.Jpeg)
                Next
                Dim xs As TimeSpan = Now - ts
                File.AppendAllText("C:\fx\renderLog.txt", doc.PageCount & vbTab & xs.TotalSeconds & vbTab & ff & vbCrLf)
            End Using

        Catch ex As Exception
            File.AppendAllText("C:\fx\render.txt", ff & vbTab & ex.ToString)
        End Try
    Next

    Dim k = 1

`

garysharp commented 7 years ago

Hey @Jodanas.

Don't forget to correctly dispose of your rendered images:

Using img = doc.Render(n, 90, 110, 72, 72, PdfiumViewer.PdfRenderFlags.None)
    img.Save("C:\fx\very\" & n & ".png", System.Drawing.Imaging.ImageFormat.Jpeg)
End Using
Jodanas commented 7 years ago

ok, thx:) This is sample, only for test.

garysharp commented 7 years ago

Did this resolve your problem?

Jodanas commented 7 years ago

Yes, thank you, work, processed all files. I do not quite understand why the fall when using existing image...

garysharp commented 7 years ago

Each time PdfDocument.Render() is called it constructs a new image. This image (reference-object) is returned and a reference to it stored in your local img variable. This variable falls out-of-scope at the Next statement. With the image now out-of-scope (has no more references to it) the garbage collector will eventually collect this object and release any managed memory.

The System.Drawing namespace is largely a wrapper around GDI+. This unmanaged API allocates memory and other resources which cannot be freed by the .NET managed garbage collector.

GDI+ has limits that can easily become relevant when objects are not disposed of correctly and cause crashes, freezing or other unexpected behaviour.

Thus the IDisposable interface is implemented on many of the objects in this namespace and Dispose() methods made available to free any unmanaged resources. This means you could technically write:

Dim img = doc.Render(n, 90, 110, 72, 72, PdfiumViewer.PdfRenderFlags.None)
img.Save("C:\fx\very\" & n & ".png", System.Drawing.Imaging.ImageFormat.Jpeg)
img.Dispose()

However the Using statement is used to provide a guarantee that the Dispose() method will be called even if an exception is thrown. So in a very simplified sense, the Using statement is similar to:

Try
    Dim img = doc.Render(n, 90, 110, 72, 72, PdfiumViewer.PdfRenderFlags.None)
    img.Save("C:\fx\very\" & n & ".png", System.Drawing.Imaging.ImageFormat.Jpeg)
Finally
    img.Dispose()
End Try

This is much nicer:

Using img = doc.Render(n, 90, 110, 72, 72, PdfiumViewer.PdfRenderFlags.None)
    img.Save("C:\fx\very\" & n & ".png", System.Drawing.Imaging.ImageFormat.Jpeg)
End Using

More information:

Jodanas commented 7 years ago

Gary, you're the best, thank you)