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
|
Sample ASP.NET website which shows how to convert PDF files into images and display them in a web browser. |
10/07/2012 | Download |
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?
Comments
veasna
#
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
Richard Moss
#
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
Bilal
#
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!