Idéias avulsas sobre assuntos variados!

Converter PDF para Imagem (JPEG) em C#

Esse vai ser o primeiro post sobre realmente o que faço no dia-a-dia, programação em C#.

Bom, é simples e rápido, estava procurando já faz um tempo de converter PDF’s pra imagem em runtime.
Procurei por toda a net e quando achei decidi publicar pois muita gente estava com a mesma dúvida.
Espero que possa ajudar!!

O que você vai precisar para fazer isso:
- Dll “gsdll32.dll” do Ghostscript, não tenho certeza se tem a DLL “solta”, mas se for o caso instale que a dll vai estar na pasta bin, do diretório de instalação.
- Copiar essa DLL para a pasta do executável (caso o projeto seja Windows Form) ou para a pasta que contém a DLL de execução do código (pasta Bin de Sites criados pelo VS2003);

[UPDATE]Como to vendo muita procura sobre esse post, vou escrever um tutorial melhor para facilitar a vida da galera que precisa usar essa ferramenta, mas primeiro vou dar uma pesquisada se não inventaram nada melhor. I’ll be back[/UPDATE]

Segue o código da classe que eu criei para converter arquivos PDF para imagens JPG:

using System;
using System.Collections;
using System.Runtime.InteropServices;


namespace Utilities.Class
{
public class PDFConvert
{
[DllImport("gsdll32.dll", EntryPoint="gsapi_new_instance")]
private static extern int gsapi_new_instance (out IntPtr pinstance, IntPtr caller_handle);

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

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

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

private string _sOutputFile;
private string _sInputFile;

private int _iWidth;
private int _iHeight;
private int _iResolutionX;
private int _iResolutionY;
private int _iJPEGQuality;

private Boolean _bFitPage;

private IntPtr _objHandle;

public GSPDFConvert(IntPtr objHandle)
{
_objHandle = objHandle;
}

public GSPDFConvert()
{
_objHandle = IntPtr.Zero;
}

public string InputFile
{
get { return _sInputFile; }
set { _sInputFile = value; }
}

public string OutputFile
{
get { return _sOutputFile; }
set { _sOutputFile = value; }
}

public int Width
{
get { return _iWidth; }
set { _iWidth = value; }
}

public int Height
{
get { return _iHeight; }
set { _iHeight = value; }
}

public int ResolutionX
{
get { return _iResolutionX; }
set { _iResolutionX = value; }
}

public int ResolutionY
{
get { return _iResolutionY; }
set { _iResolutionY = value; }
}

public Boolean FitPage
{
get { return _bFitPage; }
set { _bFitPage = value; }
}

public int JPEGQuality
{
get { return _iJPEGQuality; }
set { _iJPEGQuality = value; }
}

private byte[] StringToAnsiZ(string str)
{
//’ Convert a Unicode string to a null terminated Ansi string for Ghostscript.
//’ The result is stored in a byte array. Later you will need to convert
//’ this byte array to a pointer with GCHandle.Alloc(XXXX, GCHandleType.Pinned)
//’ and GSHandle.AddrOfPinnedObject()
int intElementCount;
int intCounter;
byte[] aAnsi;
byte bChar;

intElementCount = str.Length;
aAnsi = new byte[intElementCount+1];
for(intCounter = 0; intCounter < intElementCount;intCounter++)
{
bChar = (byte)str[intCounter];
aAnsi[intCounter] = bChar;
}

aAnsi[intElementCount] = 0;
return aAnsi;
}
public void Run()
{
int intReturn;
IntPtr intGSInstanceHandle;
object[] aAnsiArgs;
IntPtr[] aPtrArgs;
GCHandle[] aGCHandle;
int intCounter;
int intElementCount;
IntPtr callerHandle;
GCHandle gchandleArgs;
IntPtr intptrArgs;

string[] sArgs = GetGeneratedArgs();

// 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];

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();

intReturn = gsapi_new_instance(out intGSInstanceHandle, _objHandle);
callerHandle = IntPtr.Zero;
intReturn = gsapi_init_with_args(intGSInstanceHandle, intElementCount, intptrArgs);
for(intCounter = 0; intCounter
{
aGCHandle[intCounter].Free();
}
gchandleArgs.Free();
gsapi_delete_instance(intGSInstanceHandle);
gsapi_exit(intGSInstanceHandle);

}

private string[] GetGeneratedArgs()
{
// Count how many extra args are need - HRangel - 11/29/2006, 3:13:43 PM
ArrayList lstExtraArgs = new ArrayList();

if (_iJPEGQuality > 0 && _iJPEGQuality < 101)
lstExtraArgs.Add(”-dJPEGQ=” + _iJPEGQuality);

if (_iWidth > 0 && _iHeight > 0)
lstExtraArgs.Add(”-g” + _iWidth + “x” + _iHeight);

if (_bFitPage)
lstExtraArgs.Add(”-dPDFFitPage”);

if (_iResolutionX > 0)
{
if (_iResolutionY > 0)
lstExtraArgs.Add(”-r” + _iResolutionX + “x” + _iResolutionY);
else
lstExtraArgs.Add(”-r” + _iResolutionX);
}

// Load Fixed Args - HRangel - 11/29/2006, 3:34:02 PM
int iFixedCount = 7;
int iExtraArgsCount = lstExtraArgs.Count;
string[] args = new string[iFixedCount + lstExtraArgs.Count];
args[0]=”pdf2jpg”;
args[1]=”-dNOPAUSE”;
args[2]=”-dBATCH”;
args[3]=”-dSAFER”;
args[4]=”-sDEVICE=jpeg”;

for (int i=0; i < iExtraArgsCount; i++)
{
args[5+i] = (string) lstExtraArgs[i];
}

args[5 + iExtraArgsCount]=”-sOutputFile=”+_sOutputFile;
args[6 + iExtraArgsCount] = _sInputFile;

return args;
}
}
}
Se alguém precisar de ajuda pra entender o código me avisa.

Abs

7 Responses to “Converter PDF para Imagem (JPEG) em C#”

  1. Luiz Vitor said:

    O .dll para converter pode ser achado em:
    http://www.afreedll.com/dll/download/644/gsdll32.dll
    Espero ter ajudado.

  2. Henrique said:

    Cara, to com dificuldade em entender o codigo,
    qual metodo da converte o pdf para imagem e o que eu passo como parametro para ele??
    desde ja agradeço..

  3. HRangel said:

    Ola Henrique, você tem que criar uma instância dessa classe, preencher os argumentos desejados (como Input e Output file por exemplo) e em seguida executar o metodo Run do objeto criado.
    Espero poder ter ajudado

  4. minion said:

    O que é suposto passar como parametro no construtor? O que é este caller handle?

  5. minion said:

    n liga… erro meu. estou e a ter um crash ao invocar o ponteiro gsapi_exit. alguma ideia?

  6. Mauro Couto said:

    Olá Rangel,

    Excelente post acredito que tenha solucionado o problema de muita gente, no meu caso nem tanto rsrsrs

    Qaundo rodo a página aparece o seguinte erro

    Não é possível carregar a DLL ‘gsdll32.dll’: Não foi possível encontrar o módulo especificado. (Exceção de HRESULT: 0×8007007E)

    tem idéia do que pode ser? Estou usando o Visual Web Developer 2008 para desenvolver o sistema.

    até mais

  7. Mauro Couto said:

    Olá rangel,

    testei a cla

    Não é possível carregar a DLL ‘gsdll32.dll’: Não foi possível encontrar o módulo especificado. (Exceção de HRESULT: 0×8007007E)

Leave a Reply