sungaila / PDFtoImage

A .NET library to render PDF files into images.
https://www.sungaila.de/PDFtoImage/
MIT License
152 stars 15 forks source link

PDFtoImage closes stream after any operation done on it #11

Closed JBBispo closed 2 years ago

JBBispo commented 2 years ago

First of all, thank you for making PDFtoImage, it's just what I was looking for: A very lightweight package that does just that: converts PDFs to images.

I've been having some issues with it and was hoping you could provide a solution to them. I'm using PDFtoImage version 1.2.1 .NET Core 3.1 (WPF Windows Application)

After using GetPageCount, ToImage, etc, I cannot use the same Filestream (pdfStream) otherwise I'll get an exception as follows: "Cannot access a closed file"

Sample code: using (FileStream fs = File.Open(pdfPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { int imageNumber = 0; imageNumber = Conversion.GetPageCount(fs); System.Drawing.Image myImage = Conversion.ToImage(fs); //Exception occurs here }

Below is the stack trace: " at System.IO.FileStream.get_Length()\r\n at PDFtoImage.PdfiumViewer.NativeMethods.FPDF_LoadCustomDocument(Stream input, String password, Int32 id)\r\n at PDFtoImage.PdfiumViewer.PdfFile..ctor(Stream stream, String password)\r\n at PDFtoImage.PdfiumViewer.PdfDocument..ctor(Stream stream, String password)\r\n at PDFtoImage.PdfiumViewer.PdfDocument.Load(Stream stream, String password)\r\n at PDFtoImage.Conversion.ToImage(Stream pdfStream, String password, Int32 page, Int32 dpi, Nullable1 width, Nullable1 height, Boolean withAnnotations, Boolean withFormFill)\r\n "

To remediate for this, I've had to copy to separate memorystreams, like:

using (FileStream fs = File.Open(pdfPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { int imageCount = 0; using (MemoryStream fs2 = new MemoryStream()) { fs.CopyTo(fs2); imageCount = Conversion.GetPageCount(fs2); } System.Drawing.Image image = Conversion.ToImage(fs, null, 0); }

Would it be possible to add an extra argument/flag which defines if a filestream will be closed after operations are performed with it? To re-use the same filestream.

Thanks,

sungaila commented 2 years ago

Hi @JBBispo,

this is a good idea and I will implement it in the next release. Closing the Stream passed into a method is bad practice and I will fix this by introducing an optional parameter.

However, to keep the previous behavior the parameter will be something like bool closeStream = true.

Greetings, sungaila

sungaila commented 2 years ago

Hey @JBBispo, could please give 2.1.0 a try?

Please note that I replaced GDI+ with SkiaSharp so PDFtoImage.Conversion.ToImage will return a SkiaSharp.SKBitmap from now on.

JBBispo commented 2 years ago

Hello @sungaila , sorry for the delay, took longer than I thought to update to SkiaSharp. I've tested with the new version of PDFtoImage v 2.1 and everything is working correctly, so, once again, thank you very much for your quick response!