13

I need to save a one page pdf document as an image for a thumbnail on a website.

I've been messing around with PDFSharp and have had no luck.

I have tried this: http://www.pdfsharp.net/wiki/ExportImages-sample.ashx?AspxAutoDetectCookieSupport=1 but all it does is extract the embedded images in the PDF file which is not the desired result.

Ideas on how to do this? Anyone know a good library that can handle this?

Edit: Please let me know why this is such a bad question. If anyone has a good solution to this it would be a great resource for many other people. Especially since google searches come up empty.

Jason
  • 11,435
  • 24
  • 77
  • 131
  • 1
    What did you try in PDFSharp? There's an example here: http://www.pdfsharp.net/wiki/ExportImages-sample.ashx?AspxAutoDetectCookieSupport=1 – keyboardP Jan 09 '12 at 01:15
  • Show us what you've tried. We'll help you with it. –  Jan 09 '12 at 02:03
  • Thanks for the downvotes! I haven't tried anything except the example you linked which extracts the images in the PDF instead of rendering the PDF and outputting it to an image. Thats the reason I am asking: I don't see a way to do it in iTextSharp or PDFSharp. I've Googled a lot and come up empty handed. – Jason Jan 09 '12 at 03:57
  • 1
    PDFsharp cannot render PDF files - and that's what you need to create a thumbnail. This information can be found in the FAQ. You already found out that Ghostscript can do it. – I liked the old Stack Overflow Jan 09 '12 at 11:22
  • I did not downvote, but I can see this is a bad question because it has been asked many times before in SO.Just searching for "[pdf] [c#] thumbnails" will yeild 10 results. – yms Jan 11 '12 at 14:21
  • possible duplicate of [Create pdf thumbnail with C#](http://stackoverflow.com/questions/1255322/create-pdf-thumbnail-with-c-sharp) – Jason Jan 12 '12 at 16:14
  • Fair enough. Seems like votes to close because of a duplicate question would be the proper route. I voted to close it as a dupe of http://stackoverflow.com/questions/1255322/create-pdf-thumbnail-with-c-sharp. – Jason Jan 12 '12 at 16:14

5 Answers5

6

Take a look at Ghostscript. You can render PDF to images with it.

http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/

Jason
  • 11,435
  • 24
  • 77
  • 131
  • Works like a champ. I recommend getting the source. It is easier to follow and it is also a bit different that the example on the blog. The only thing is you have to know the desired width/height. I guess I'll work on figuring out where to glean that information from. – Jason Jan 09 '12 at 04:48
  • I'm not crazy about this solution, other than the fact that it works. If anyone has a better solution let us know and I'll give you the checkmark. – Jason Jan 09 '12 at 04:49
  • what was your solution for getting the page size on the pdf? – David Freire Mar 24 '15 at 18:15
6

Ghostscript is currently the de-facto standard for rendering PDFs. It's a bit tricky to wrap, even using GhostScriptSharp.

Jason Morse wrote a great C# wrapper for rendering PDFs as a plugin to the open-source imageresizing.net library.

If it's an asp.net application, the library allows on-the-fly rendering, so you can just add a querystring to get the jpeg/png version:

/pdfs/letter.pdf?format=jpg&page=2

You can also use the managed API instead (in any application type - not asp.net specific)

ImageBuilder.Current.Build("letter.pdf","dest.jpg",new ResizeSettings("format=jpg;page=2"));

The PdfRenderer plugin is GPL licensed, just like Ghostscript.

Lilith River
  • 16,204
  • 2
  • 44
  • 76
2

ABCpdf exports PDF documents to JPEG with C#. See: http://www.websupergoo.com/helppdfnet/source/4-examples/19-rendering.htm

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
AffineMesh
  • 1,025
  • 8
  • 14
  • I will take a look at this and see if its cleaner than using Ghostscript(It has to be). Thanks! – Jason Jan 18 '12 at 22:02
1

(disclaimer: I work for Atalasoft and wrote a lot of the PDF technology) If you use the PdfDecoder in Atalasoft dotImage, this is straight forward:

public void PdfToJpegThumb(Stream srcStream, int pageNo, int maxDimension, Stream dstStream)
{
    PdfDecoder decoder = new PdfDecoder();
    decoder.Resolution = 96; // reduce default resolution to speed up rendering
    // render page
    using (AtalaImage pdfimage = decoder.read(srcStream, pageNo, null)) {
        Thumbnail tn = new Thumbnail(maxDimension, maxDimension);
        // make a thumbnail image
        using (AtalaImage tnImage = tn.Create(pdfImage)) {
            // save it
            tnImage.Save(dstStream, new JpegEncoder(), null);
        }
    }
}
plinth
  • 48,267
  • 11
  • 78
  • 120
0

I got this from somewhere on the web - can't remember exactly where but it works for me!
I just made it into a nice function.

It uses the GhostScript APIs (GSdll32.dll)

Examples of the imageFormat parameter are "jpeg", "tiff32nc", etc.

    #region GhostScript API functions
    [DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance")]
    private static extern int CreateAPIInstance(out IntPtr pinstance,
                                            IntPtr caller_handle);

    [DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
    private static extern int InitAPI(IntPtr instance, int argc, IntPtr argv);

    [DllImport("gsdll32.dll", EntryPoint = "gsapi_exit")]
    private static extern int ExitAPI(IntPtr instance);

    [DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance")]
    private static extern void DeleteAPIInstance(IntPtr instance);
    #endregion

    public bool CreateImage(string inputPath, string outputPath, string imageFormat, int firstPage, int lastPage, int width, int height)
    {
        bool result = false;
        try
        {
            string[] args = GetArgs(inputPath, outputPath, imageFormat, firstPage, lastPage, width, height);
            var argStrHandles = new GCHandle[args.Length];
            var argPtrs = new IntPtr[args.Length];

            // Create a handle for each of the arguments after 
            // they've been converted to an ANSI null terminated
            // string. Then store the pointers for each of the handles
            for (int i = 0; i < args.Length; i++)
            {
                argStrHandles[i] = GCHandle.Alloc(StringToAnsi(args[i]), GCHandleType.Pinned);
                argPtrs[i] = argStrHandles[i].AddrOfPinnedObject();
            }

            // Get a new handle for the array of argument pointers
            var argPtrsHandle = GCHandle.Alloc(argPtrs, GCHandleType.Pinned);

            // Get a pointer to an instance of the GhostScript API 
            // and run the API with the current arguments
            IntPtr gsInstancePtr;
            CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
            InitAPI(gsInstancePtr, args.Length, argPtrsHandle.AddrOfPinnedObject());

            // Cleanup arguments in memory
            for (int i = 0; i < argStrHandles.Length; i++)
                argStrHandles[i].Free();

            argPtrsHandle.Free();

            // Clear API
            ExitAPI(gsInstancePtr);
            DeleteAPIInstance(gsInstancePtr);

            result = true;
        }
        catch(Exception e)
        {
            throw e;
        }
        return result;
    }
CompanyDroneFromSector7G
  • 4,291
  • 13
  • 54
  • 97
  • Its taken from http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/. Also, you are missing all the helper methods like 'GetArgs' etc – Jason Jan 19 '12 at 16:56