This content has moved - please find it at https://devblog.cyotek.com.

Although these pages remain accessible, some content may not display correctly in future as the new blog evolves.

Visit https://devblog.cyotek.com.

Displaying the contents of a PDF file in an ASP.NET application using GhostScript

After receiving quite a few requests on making the PDF image conversion work in a web application, I wanted to see how hard it would be to do. Not hard at all as it turns out, I had a nice working sample running with a bare 5 minutes of work.

The sample available for download below is a basic ASP.NET application, comprised of a single page with an IHttpHandler for displaying the image. In order to make this sample as easy as possible, it uses pure server side controls and code, nothing client side.

Getting Started

In order to run this sample, you'll need the Cyotek.GhostScript and Cyotek.GhostScript.PdfConversion.zip components described in a previous article.

You'll also need to download GhostScript. As with my other articles on the subject, please make sure you check their license terms - they seem very keen that people don't use the GPL version or distribute GhostScript without a commercial license.

Locating gsdll32.dll

In order for this to work, gsdll32.dll needs to be somewhere in your applications path. This could be in your system32 directory on 32bit Windows, or SysWOW64 on 64bit Windows.

While developing this sample, I also tried having the file in the bin directory of the website - this also worked fine. However, as the website was running on my local machine, it's probably running in Full Trust, and I have no idea if it will work in Medium Trust or lower.

I'm running 64bit Windows

Congratulations! I have nothing but issues with 32bit web servers. But I digress. The sample projects I have provided on this website all use the 32bit version of GhostScript. There is a 64bit version available, but I haven't downloaded it to test. Your options should be as follows:

  • Build against the 64bit GhostScript DLL. This may need some refactoring if their public API has changed. At the very least, you'll need to change the DLL filename in the native method calls.
  • Using IIS7 or higher? Keep using the 32bit version, and set your worker pool to run in 32bit mode
  • Using IIS6? Commiserations, I feel your pain. The only option here, if you stay 32bit, is to have the entire IIS run as 32bit.

I have tested on a Windows 7 Professional 64bit machine as follows:

  • Firstly, using IISExpress which is running as a 32bit process
  • Secondly, using IIS7 with a custom application pool running in 32bit mode

Both of these scenarios worked perfectly well.

Creating the solution

Create a new ASP.NET Web Forms Site

Note: Even though this example uses pure WebForms, there's no reason that this sort of code won't work fine in ASP.NET MVC or any other .NET framework of your choice.

Open up Default.aspx and add some controls similar to the following:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GhostScriptWebTest._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>PDF Conversion Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <p>
            <asp:LinkButton runat="server" ID="previousLinkButton" Text="Previous" OnClick="previousLinkButton_Click" />
            <asp:LinkButton runat="server" ID="nextLinkButton" Text="Next" OnClick="nextLinkButton_Click" />
        </p>
        <p>
            <asp:Image runat="server" ID="pdfImage" ImageUrl="~/PdfImage.ashx?fileName=sample.pdf&page=1" />
        </p>
    </div>
    </form>
</body>
</html>

The controls should be fairly self explanatory! The main thing of interest is the pdfImage Image control - this will call a Generic Handler that I'll describe in the next section. Note that VS2010 and VS2012 have another option, an ASP.NET Handler - this implements the same IHttpHandler interface but doesn't have a .ashx file and is registered differently. If you are using IIS7 or above, you're probably better off using that.

Note that by default the pdfImage control is pointing to a sample file named sample.pdf - add any old PDF to the root of your website and name it sample. Ensure that the Build Action for the PDF is set to Content, otherwise it won't be deployed with your application.

Creating the image handler

Tutorials on creating image handlers with IHttpHandler can be found scattered throughout the net, so I'll not go into how they work, but just describe the implementation I'm using in this example. Add a new generic handler to your project, then fill in the ProcessRequest method as follows. Make sure you add the two GhostScript API components to your solution and add references to them to your web application first!

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web;
using Cyotek.GhostScript.PdfConversion;

namespace GhostScriptWebTest
{
  public class PdfImage : IHttpHandler
  {
    public void ProcessRequest(HttpContext context)
    {
      string fileName;
      int pageNumber;
      Pdf2Image convertor;
      Bitmap image;

      fileName = context.Server.MapPath("~/" + context.Request.QueryString["fileName"]);
      pageNumber = Convert.ToInt32(context.Request.QueryString["page"]);

      // convert the image
      convertor = new Pdf2Image(fileName);
      image = convertor.GetImage(pageNumber);

      // set the content type
      context.Response.ContentType = "image/png";

      // save the image directly to the response stream
      image.Save(context.Response.OutputStream, ImageFormat.Png);
    }

    public bool IsReusable
    { get { return true; } }
  }
}

Again, this is extremely simple code. I extract the query string of the request to obtain the file name of the PDF document to convert, and the page to display. I then create an instance of the Pdf2Image class, and grab an image of the specified page.

Next, you need to set the ContentType of the Response object so the web browser knows what to do with your content. Finally, I save the image directly to the response's OutputStream. Make sure that the format you save the image as matches the content type you've specified.

With these steps complete, building and running the website should present you with a pair of hyper links, and the first page of your PDF file as a static image. [Well, it will if you add a pair of blank event handlers for those defined for the two hyperlink buttons anyway]

Simple navigation

Now that we can display our PDF, we'll add some basic navigation. Open up the code behind file for Default.aspx and fill in the event handlers for the two hyperlink buttons.

using System;
using System.Collections.Specialized;
using System.Web;
using Cyotek.GhostScript.PdfConversion;

namespace GhostScriptWebTest
{
  public partial class _Default : System.Web.UI.Page
  {
    protected void previousLinkButton_Click(object sender, EventArgs e)
    {
      this.IncrementPage(-1);
    }

    protected void nextLinkButton_Click(object sender, EventArgs e)
    {
      this.IncrementPage(1);
    }

    private void IncrementPage(int increment)
    {
      NameValueCollection queryString;
      int pageNumber;
      string pdfFileName;
      Pdf2Image converter;

      queryString = HttpUtility.ParseQueryString(pdfImage.ImageUrl.Substring(pdfImage.ImageUrl.IndexOf("?")));
      pdfFileName = queryString["fileName"];
      pageNumber = Convert.ToInt32(queryString["page"]) + increment;
      converter = new Pdf2Image(this.Server.MapPath("~/" + pdfFileName));

      if (pageNumber > 0 && pageNumber <= converter.PageCount)
        pdfImage.ImageUrl = string.Format("~/PdfImage.ashx?fileName={0}&page={1}", pdfFileName, pageNumber);
    }
  }
}

As with the image handler, this code simply extracts the file name of the PDF file and the current page number. It also creates a new instance of the Pdf2Image class in order to obtain the number of pages in the document. If the new page number is in range, it updates the ImageUrl of the pdfImage causing the image handler to pull back the next page.

In Conclusion

This sample is pretty inefficient and at the very least should be caching the images. But, it's as simple an example as I can make. Hopefully someone will find it useful. At the present time I'm not working with the GhostScript API library so I suspect this will be the last article on the subject for the time being.

Update History

  • 2012-07-10 - First published
  • 2020-11-21 - Updated formatting

Downloads

Filename Description Version Release Date
GhostScriptWebTest.zip
  • md5: 0b163c5c6596db5940457e81286ce656

Sample ASP.NET website which shows how to convert PDF files into images and display them in a web browser.

10/07/2012 Download

About The Author

Gravatar

The founder of Cyotek, Richard enjoys creating new blog content for the site. Much more though, he likes to develop programs, and can often found writing reams of code. A long term gamer, he has aspirations in one day creating an epic video game. Until that time, he is mostly content with adding new bugs to WebCopy and the other Cyotek products.

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported

Comments

Gravatar

veasna

# Reply

Good evening,

I can not make it works on my aspx, with C# code. Do you have a complete working sample which is just having single page? By the way, does Pdf2Image class is part of GhostScript Library or it is in another library?

Best regards,

Veasna

Gravatar

Richard Moss

# Reply

Hello,

The example project for this article requires both libraries from the article available at http://www.cyotek.com/blog/convert-a-pdf-into-a-series-of-images-using-csharp-and-ghostscript, in addition to GhostScript itself. The example was working perfectly well when I first wrote it, although I haven't looked at GhostScript since publishing these, and probably won't be revisiting the subject anytime soon.

Regards; Richard Moss

Gravatar

Bilal

# Reply

hi,its works perfect on my local windows 7. it's not working on windows server 64 bit ,although i change application pool to 32 bit Enable True. please help!