Click here to Skip to main content
15,917,968 members
Articles / Programming Languages / C#

How To Convert PDF to Image Using Ghostscript API

Rate me:
Please Sign up or sign in to vote.
4.89/5 (76 votes)
28 Mar 2010CPOL4 min read 2.1M   45.3K   229   405
How to use Ghostscript library to create an image (or images) from a PDF file

Where to Download the Required Library

You will need at least GhostScript 8.64 (other versions have a problem with Vista). After you have installed the program, just copy the gs32dll.dll from the installation directory (the bin subdirectory) to the directory where you have the EXE of my program.


The program REQUIRES the DLL of Ghostscript, it can be retrieved from the Ghostscript website.


Often, I found the need to perform a conversion from a PDF to an image format.

Be it TIF, JPG or whatever format (I strongly suggest to convert PDF to PNG and NOT to JPEG since PNG is MUCH smaller and much better (since it has no information losses). Try for yourself and you will see!)

I found many programs and controls that allow me to do it but they are all expensive or incomplete for my needs. Since I know that Ghostscript performs this kind of work pretty well, I looked for a way to automate a simple conversion.


To perform a conversion, I needed to pass several commands to the Ghostscript interpreter. I must convert a Unicode string to a null terminated ANSI string for Ghostscript. The result is stored in a byte array.

The parameters that we will provide the library are the same and in the same order that we should provide from the command line. So in case any modification attempt should fail on this project, be sure that they are working from the command line!

For a comprehensive list of all the parameters and their meanings, I suggest you read: How to use Ghostscript.

How to Interface with the Ghostscript Library

The functions that are needed to call the library must be invoked using P/Invoke:

/// <summary>Create a new instance of Ghostscript.</summary>
/// <param name="pinstance"></param>
/// <param name="caller_handle"></param>
/// <returns>The instance passed to other GS function</returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_new_instance")]
private static extern int gsapi_new_instance (out IntPtr pinstance,
    IntPtr caller_handle);
/// <summary>This will make the conversion</summary>
/// <param name="instance"></param><param name="argc"></param><param name="argv"></param>
/// <returns>0 if is ok</returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_init_with_args")]
private static extern int gsapi_init_with_args (IntPtr instance, int argc, IntPtr argv);
/// <summary>Exit the interpreter</summary>
/// <param name="instance"></param><returns></returns>
[DllImport("gsdll32.dll", EntryPoint="gsapi_exit")]
private static extern int gsapi_exit (IntPtr instance);
/// <summary>Destroy an instance of Ghostscript.</summary>
/// <param name="instance"></param>
[DllImport("gsdll32.dll", EntryPoint="gsapi_delete_instance")]
private static extern void gsapi_delete_instance (IntPtr instance);

Now that we have this function, we MUST call them in this order:

  1. gsapi_new_instance
  2. gsapi_init_with_args
  3. gsapi_exit
  4. gsapi_delete_instance

Pay attention to the last two, it is a common mistake to invert them!

Now how to call it. (In the real code, there are also parameter checks, but I skip them here for simplicity):

/// <summary>Convert a single file!</summary>
/// <param name="inputFile">The file PDf to convert</param>
/// <param name="outputFile">The image file that will be created</param>
/// <returns>True if the conversion succeeds!</returns>
public bool Convert(string inputFile,string outputFile)
    //These are the variables that I'm going to use
    int intReturn,intCounter,intElementCount;
    IntPtr intGSInstanceHandle;
    object[] aAnsiArgs;
    IntPtr[] aPtrArgs;
    GCHandle[] aGCHandle;
    IntPtr callerHandle, intptrArgs;
    GCHandle gchandleArgs;
    //Generate the list of the parameters
    string[] sArgs = GetGeneratedArgs(inputFile,outputFile);
    // Convert the Unicode strings to null terminated ANSI byte arrays
    // then get pointers to the byte arrays.
    intElementCount = sArgs.Length;
    aAnsiArgs = new object[intElementCount];
    aPtrArgs = new IntPtr[intElementCount];
    aGCHandle = new GCHandle[intElementCount];
    //Convert the parameters
    for(intCounter = 0; intCounter< intElementCount; intCounter++)
        aAnsiArgs[intCounter] = StringToAnsiZ(sArgs[intCounter]);
        aGCHandle[intCounter] =
                 GCHandle.Alloc(aAnsiArgs[intCounter], GCHandleType.Pinned);
        aPtrArgs[intCounter] = aGCHandle[intCounter].AddrOfPinnedObject();
    gchandleArgs = GCHandle.Alloc(aPtrArgs, GCHandleType.Pinned);
    intptrArgs = gchandleArgs.AddrOfPinnedObject();
    //Create a new instance of the library!
        intReturn = gsapi_new_instance(out intGSInstanceHandle, _objHandle);
        //Be sure that we create an instance!
        if (intReturn < 0)
            MessageBox.Show("I can't create a new instance of Ghostscript
                                   please verify no other instance are running!");
            //Here you should also clean the memory
            ClearParameters(ref aGCHandle,ref gchandleArgs);
            return false;        }
    catch (DllNotFoundException ex)
    {//in this case the DLL we are using is not the DLL we expect
        MessageBox.Show("The gs32dll.dll in the program directory
                 doesn't expose the methods i need!
                 \nplease download the version 8.63 from the original website!");
        return false;
    callerHandle = IntPtr.Zero;//remove unwanted handler
    intReturn = -1;//if nothing changes, it is an error!
    //Ok now is the time to call the interesting module
    try {intReturn =
         gsapi_init_with_args(intGSInstanceHandle, intElementCount, intptrArgs);}
    catch (Exception ex)  { MessageBox.Show(ex.Message);}
    finally//No matter what happens, I MUST close the instance!
    {   //free all the memory
        ClearParameters(ref aGCHandle,ref gchandleArgs);
        gsapi_exit(intGSInstanceHandle);//Close the instance
        gsapi_delete_instance(intGSInstanceHandle);//delete it
    //Conversion was successful if return code was 0 or e_Quit
    return (intReturn == 0) | (intReturn == e_Quit);//e_Quit = -101

How to Call the Library We Just Created

Using this library is pretty simple.

  1. Create an instance of the class
  2. Provide the parameters that are passed as properties (this is optional now)
  3. Call the function: "Convert" with input and output name (optionally even the parameters)

Here there is an example:

/// <summary>Convert a single file</summary>
/// <remarks>this function PRETEND that the filename is right!</remarks>
private void ConvertSingleImage(string filename)
    //Setup the converter
    converter.FirstPageToConvert = (int)numericFirstPage.Value;
    converter.LastPageToConvert = (int)numericLastPage.Value;
    converter.FitPage = checkFitTopage.Checked;
    converter.JPEGQuality = (int)numQuality.Value;
    converter.OutputFormat = comboFormat.Text;
    System.IO.FileInfo input = new FileInfo(filename);
    string output = string.Format("{0}\\{1}{2}",
    //If the output file exists already, be sure to add a
    //random name at the end until it is unique!
    while (File.Exists(output))
        output = output.Replace(txtExtension.Text,
         string.Format("{1}{0}", txtExtension.Text,DateTime.Now.Ticks));
    txtArguments.Text = converter.ParametersUsed;
    if (converter.Convert(input.FullName, output) == true)
        lblInfo.Text = string.Format("{0}:File converted!",
        lblInfo.Text = string.Format("{0}:File NOT converted!
                          Check Args!", DateTime.Now.ToShortTimeString());

Remark About the Library

Ghostscript isn't threadsafe, if you call it more than once, you MUST provide a lock system to be sure you are not calling two instances at the same time.

How to Use This as a Library

Since I have seen a lot of problems regarding how to use this library, I split my project in 2 main projects, one is a DLL (PDFToImage.dll) and the other one is the simple GUI of the DLL.

To use it in an ASP page, YOU MUST set the property "ThrowException" to true and now the library will only throw an exception on error and not show any Messagebox (that you could not want on an ASP page for example).

In case your needs are different from mine, I added a way to pass the library directly the parameters you want. In this case, you will only have to provide input, output name and a string with the parameters as usual in the same form and order then you would provide the command line.

If you want to use this library in an ASP.NET page, you MUST copy both PDFToImage.dll and gs32dll.dll in the BIN directory of your solution!

How to Debug Problems

The program displays a nice arguments list that will help you to find why a file doesn't convert! Open a command prompt, enter the directory where you installed Ghostscript and execute the file gs32win.exe with the parameters as expressed in the textbox (you should only add " to enclose the path of the file that are the last 2 arguments).

You will see how the real Ghostscript would react to it, so you will understand why an error occurred!


  • 1.0.3 (2008 January): Initial version
  • 1.1.0 (2009 March 25): Made it possible to use as DLL and to pass other parameters
  • 1.1.1 (2009 March 26): Fixed an International issue, thanks to tchu_2000
  • 1.1.2b (2009 March 27): Fixed multiple page output, and cleaned up the International convention
  • 1.1.3 (2009 April 4): Fixed duplicated parameter, added new parameters option (PageSize, Multithreads support, AntiAlaising and so on)
  • 1.2 (2009 November 17): Fixed bug in parameter (thanks Barabara), added more font Options (Thanks Davalv), added Mutex to avoid Concurrency issue (Thanks Davalv), added recognition of 64bit problems


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Web Developer
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

PraiseSaved my life! Pin
Ali Agha22-Aug-20 1:52
Ali Agha22-Aug-20 1:52 
GeneralRe: Saved my life! Pin
Chuck Salerno 20215-Aug-22 11:21
Chuck Salerno 20215-Aug-22 11:21 
QuestionAn attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)' Pin
Member 148718677-Jul-20 1:43
Member 148718677-Jul-20 1:43 
AnswerRe: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)' Pin
Chuck Salerno 20215-Aug-22 1:33
Chuck Salerno 20215-Aug-22 1:33 
AnswerRe: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)' Pin
Mister Zi Cold30-Oct-23 22:58
Mister Zi Cold30-Oct-23 22:58 
PraisePretty Slick Pin
Member 140419682-Nov-18 11:20
Member 140419682-Nov-18 11:20 
QuestionThank you! This saved me a bit of money and, most importantly, time. Pin
Member 110382242-May-18 19:33
Member 110382242-May-18 19:33 
QuestionConverted PDF imgs stored/accessed in memory instead of saved as files? Pin
Member 1329514627-Jul-17 10:32
Member 1329514627-Jul-17 10:32 
QuestionCan I convert multi page pdf to multi page tiff images Pin
Member 131723804-May-17 4:21
Member 131723804-May-17 4:21 
QuestionHow to get the best quality? Pin
wesbyte29-Dec-16 18:32
wesbyte29-Dec-16 18:32 
GeneralSupport Pin
skymark25-Aug-16 16:10
skymark25-Aug-16 16:10 
QuestionImage in memory Pin
DamonLeedham8-Jun-16 0:36
DamonLeedham8-Jun-16 0:36 
QuestionHow to convert pdf to image? Pin
louisj16-May-15 1:52
louisj16-May-15 1:52 
QuestionWorks great .... Thank you! Pin
Ali Cameron27-Mar-15 7:31
Ali Cameron27-Mar-15 7:31 
QuestionCan't get beyond "File NOT converted check args" Pin
JamesParsons20-Jan-15 16:23
JamesParsons20-Jan-15 16:23 
QuestionQuestion about image scaling Pin
MatthysDT21-Dec-14 21:22
MatthysDT21-Dec-14 21:22 
AnswerRe: Question about image scaling Pin
dgogoasa4-Sep-16 16:17
dgogoasa4-Sep-16 16:17 
AnswerRe: Question about image scaling Pin
dgogoasa4-Sep-16 16:28
dgogoasa4-Sep-16 16:28 
QuestionUnable to find an entry point named 'gsapi_new_instance in DLL 'gsdll32.dll'. Pin
Member 112992089-Dec-14 18:56
Member 112992089-Dec-14 18:56 
AnswerRe: Unable to find an entry point named 'gsapi_new_instance in DLL 'gsdll32.dll'. Pin
SivaKtamilan1-Jul-15 2:58
SivaKtamilan1-Jul-15 2:58 
QuestionUnable to find an entry point named 'gsapi_revision' in DLL 'gsdll32.dll'. Pin
Member 43355204-Nov-14 4:47
Member 43355204-Nov-14 4:47 
SuggestionMutex should be an unnamed one? Pin
dmet14-Oct-14 2:04
dmet14-Oct-14 2:04 
QuestionGetting following error with 7 64 bit OS Pin
simpa26-Sep-14 5:23
simpa26-Sep-14 5:23 
AnswerWorked well in my testing! Thanks! Pin
AdeleB13-Aug-14 17:36
AdeleB13-Aug-14 17:36 
QuestionNo tengo el ejecutable o .exe Pin
HUGO AEXANDER3-Aug-14 8:26
HUGO AEXANDER3-Aug-14 8:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.