0

I'm trying convert from digitally signed PDF to PNG using this solution: Simple VB.Net Wrapper for Ghostscript Dll. It doesn't work for me too. I'm using Ghostscript 9.18 32bits.

First, the source code goes to InOutErrCallBack method in this part:

gsapi_init_with_args(InstanceHndl, NumArgs + 1, Args)

When this occurr, the execution freeze. After this occurs, the next calls to RunGS method returns false in this part:

If gsapi_new_instance(InstanceHndl, IntPtr.Zero) <> 0 Then
    Return False
    Exit Function
End If

The return value of gsapi_new_instance is -100: Ghostscript API - Return codes

The gswin32.dll is in C:\Windows\System32 and BIN project folder.

My parameter sequence:

Dim outputImgPath As String
outputImgPath = "C:\Download\DocumentosV2\Protocolo\Pronunciamento\" + Guid.NewGuid.ToString("N") + ".png"

Dim args() As String = { _
    "-dNOPAUSE", _
    "-dBATCH", _
    "-dSAFER", _
    "-dQUIET", _
    "-sDEVICE=png16m", _
    String.Format("-r{0}", resolucao), _
    "-dTextAlphaBits=2", _
    "-dGraphicsAlphaBits=2", _
    String.Format("-dFirstPage={0}", pageNumber), _
    String.Format("-dLastPage={0}", pageNumber), _
    String.Format("-sOutputFile={0}", outputImgPath), _
    "-f", _
    pdfPath _
    }

UPDATE

@kens advise me for some arguments. So, I remove it to test.

My Complete code:

Imports PdfSharp
Imports System
Imports System.Collections
Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports PdfSharp.Pdf
Imports PdfSharp.Pdf.IO
Imports PdfSharp.Drawing

'''
''' http://www.geekscrapbook.com/2009/11/16/c-method-to-add-an-image-to-a-pdf/
'''
Public Class PDF2Image2PDF
    Inherits Simp.Net.Infra.SimpComponent

    Private SyncRoot As New Object

    'Converte cada página do PDF em imagem
    Public Function Pdf2Png(ByVal pdfPath As String, ByVal resolucao As Int32) As Image()

        Dim outputImgPath As String
        Dim pageCount As Integer

        Dim objPdfReader As New iTextSharp.text.pdf.PdfReader(pdfPath)
        pageCount = objPdfReader.NumberOfPages()

        Dim objImages As New ArrayList

        For pageNumber As Int32 = 1 To pageCount
            outputImgPath = "C:/Download/DocumentosV2/Protocolo/Pronunciamento/" + Guid.NewGuid.ToString("N") + ".png"
            Dim objFileStream As FileStream
            Dim objMemoryStream As MemoryStream

            'Dim args() As String = { _
            '    "-dNOPAUSE", _
            '    "-dBATCH", _
            '    "-dSAFER", _
            '    "-dQUIET", _
            '    "-sDEVICE=png16m", _
            '    String.Format("-r{0}", resolucao), _
            '    "-dTextAlphaBits=2", _
            '    "-dGraphicsAlphaBits=2", _
            '    String.Format("-dFirstPage={0}", pageNumber), _
            '    String.Format("-dLastPage={0}", pageNumber), _
            '    String.Format("-sOutputFile={0}", outputImgPath), _
            '    "-f", _
            '    pdfPath _
            '    }

            Dim args() As String = { _
                "-dNOPAUSE", _
                "-dBATCH", _
                "-sDEVICE=png16m", _
                String.Format("-dFirstPage={0}", pageNumber), _
                String.Format("-dLastPage={0}", pageNumber), _
                String.Format("-sOutputFile={0}", outputImgPath), _
                Replace(pdfPath, "\", "/") _
                }

            If GhostscriptDllLib.RunGS(args) Then
                If File.Exists(outputImgPath) Then
                    objFileStream = New FileStream(outputImgPath, FileMode.Open)
                    Dim length As Int32 = objFileStream.Length
                    Dim bytes(length) As Byte
                    objFileStream.Read(bytes, 0, length)
                    objFileStream.Close()

                    objMemoryStream = New MemoryStream(bytes, False)

                    objImages.Add(Image.FromStream(objMemoryStream))
                Else
                    Throw New InvalidOperationException("Erro ao converter páginas do PDF em imagens PNG")
                End If
            Else
                Throw New InvalidOperationException("Erro ao converter páginas do PDF em imagens PNG")
            End If

        Next

        Return CType(objImages.ToArray(GetType(Image)), Image())

    End Function

    'Converte cada imagem do vetor em uma página do PDF
    Public Function Images2PDF(ByVal imagens() As Image) As PdfDocument
        Dim pdf As PdfDocument
        Dim gfx As XGraphics
        Dim ximg As XImage

        pdf = New PdfDocument

        For Each img As Image In imagens
            pdf.AddPage(New PdfPage)
            gfx = XGraphics.FromPdfPage(pdf.Pages.Item(0))
            ximg = XImage.FromGdiPlusImage(img)

            gfx.DrawImage(ximg, 0, 0)

            ximg.Dispose()
            gfx.Dispose()

        Next

        Return pdf
    End Function

End Class

The Caller code:

Public Sub DownloadPeticionamento(ByVal sender As System.Object, ByVal e As System.web.UI.ImageClickEventArgs)
    Dim imagem As ImageButton = DirectCast(sender, ImageButton)
    Dim pdfPath As String = imagem.DescriptionUrl

    Dim objPdfPeticionamento As New Simp.Net.Negocio.PDF2Image2PDF

    Dim objImages() As Image
    Dim objPdfDoc As PdfDocument
    objImages = objPdfPeticionamento.Pdf2Png(pdfPath, 600)

    objPdfDoc = objPdfPeticionamento.Images2PDF(objImages)
    objPdfDoc.Save(Me.Page.Response.OutputStream, True)

End Sub

I test this in command line to:

gswin32c -dNOPAUSE -dBATCH -sDEVICE=png16m -sOutputFile=C:/Download/DocumentosV2/Protocolo/Pronunciamento/fb21872746b64f8fb31b3764b5444e2e.png C:/Upload/DocumentosV2/Protocolo/Pronunciamento/3_0_404702190_2016_10081288_230_0_f1f09b4b38ac49a8a3e5576f6041eea3.pdf

Via command line, the pdf is converted. The command line output:

C:\Documents and Settings\leandro.ferreira>gswin32c -dNOPAUSE -dBATCH -sDEVICE=png16m -dFirstPage=1 -dLastPage=1 -sOutputFile=C:/Download/DocumentosV2/Protocolo/Pronunciamento/fb21872746b64f8fb31b3764b5444e2e.png C:/Upload/DocumentosV2/Protocolo/Pronunciamento/3_0_404702190_2016_10081288_230_0_f1f09b4b38ac49a8a3e5576f6041eea3.pdf
GPL Ghostscript 9.16 (2015-03-30)
Copyright (C) 2015 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Can't find (or can't open) font file %rom%Resource/Font/Arial-BoldMT.
Can't find (or can't open) font file Arial-BoldMT.
Can't find (or can't open) font file %rom%Resource/Font/Arial-BoldMT.
Can't find (or can't open) font file Arial-BoldMT.
Querying operating system for font files...
Didn't find this font on the system!
Substituting font Helvetica-Bold for Arial-BoldMT.
Loading NimbusSan-Bol font from %rom%Resource/Font/NimbusSan-Bol... 4047240 2487522 8937716 7603550 3 done.
Can't find (or can't open) font file %rom%Resource/Font/ArialMT.
Can't find (or can't open) font file ArialMT.
Can't find (or can't open) font file %rom%Resource/Font/ArialMT.
Can't find (or can't open) font file ArialMT.
Didn't find this font on the system!
Substituting font Helvetica for ArialMT.
Loading NimbusSan-Reg font from %rom%Resource/Font/NimbusSan-Reg... 4080352 2580805 9014744 7662839 3 done.

C:\Documents and Settings\leandro.ferreira>
Community
  • 1
  • 1
Soriano
  • 103
  • 3

2 Answers2

0

-100 is simply 'fatal error' ie something really bad happened. More information is generally printed to stdout or stderr, of course setting -dQUIET will suppress much of this....

Since you are getting -100 returned its almost certainly the case that your arguments to Ghostscript are incorrect in some way.

The absolute first thing you should do when debugging problems is to try and simplify the problem, so remove any switches that you don't unquestionably require.

So the first thing to do is to remove the -dQUIET, capture all the stdout/stderr output and tell us what it says.

Further to that, note the following:

You don't need '-f' because the only purpose of that switch is to terminate -c which you haven't used.

You haven't given the values of 'resolucao', 'pageNumber', or 'pdfPath' or so there's no way to know if those are valid (or sensible). The path you have specified for outputImgPath is quite long, and includes the backslash character. I would advise using the forward slash '/' instead, as backslash is used to begin an escape and can give results you may not expect.

You've also used -dSAFER, do you understand the implications of specifying this ? If not, remove it and try again.

When you have created the string 'args' print it out. At the very least this will give you something you can try from the command line, and may mean that other people have some chance of reproducing your problem.

Finally; please note that Ghostscript is distributed under the Affero General Public Licence, please be sure to read the licence and ensure that you are conforming to the terms contained therein.

KenS
  • 30,202
  • 3
  • 34
  • 51
  • Thank you to answer, @kens. The pdfPath is a digitally signed PDF with multiples pages, so, pageNumber varying between 1 and last page of this pdf. I remove `-f`, `-dQUIET`, `-dSAFER`, `-r`, `-dTextAlphaBits`, `-dGraphicsAlphaBits`, `-dFirstPage` and `-dLastPage` to debugging this code. Doing this, the command line is: `gswin32c -dNOPAUSE -dBATCH -sDEVICE=png16m -sOutputFile=C:/Download/DocumentosV2/Protocolo/Pronunciamento/fb21872746b64f8fb31b3764b5444e2e.png C:\Upload\DocumentosV2\Protocolo\Pronunciamento\3_0_404702190_2016_10081288_230_0_f1f09b4b38ac49a8a3e5576f6041eea3.pdf`. – Soriano Feb 17 '16 at 17:49
0

To do this work, I modified the Simple VB.Net Wrapper for Ghostscript Dll CallBack:

Private Function InOutErrCallBack(ByVal handle As IntPtr, _
  ByVal Strz As IntPtr, ByVal Bytes As Integer) As Integer

    Dim objString As String
    objString = Marshal.PtrToStringAnsi(Strz, Bytes)

    System.Diagnostics.Debug.WriteLine(objString)

    Return Bytes

End Function

This wrotes the Ghostscript output into the Output window's Visual Studio 2003. I removed the extra "needless" arguments to Ghostscript, like -dGraphicsAlphaBits. The asp.net user does not access the Path.GetTempDir, so, I need a different "temp" dir.

'Converte cada página do PDF em imagem
Public Function Pdf2Png(ByVal pdfPath As String, ByVal tempDirPath As String, ByVal resolucao As Int32) As Image()

    Dim outputImgPath As String
    Dim pageCount As Integer

    Dim objPdfReader As New iTextSharp.text.pdf.PdfReader(pdfPath)
    pageCount = objPdfReader.NumberOfPages()

    Dim objImages As New ArrayList

    For pageNumber As Int32 = 1 To pageCount
        outputImgPath = tempDirPath + Guid.NewGuid.ToString("N") + ".png"

        Dim objFileStream As FileStream
        Dim objMemoryStream As MemoryStream

        'Dim args() As String = { _
        '    "-dNOPAUSE", _
        '    "-dBATCH", _
        '    "-dSAFER", _
        '    "-dQUIET", _
        '    "-sDEVICE=png16m", _
        '    String.Format("-r{0}", resolucao), _
        '    "-dTextAlphaBits=2", _
        '    "-dGraphicsAlphaBits=2", _
        '    String.Format("-dFirstPage={0}", pageNumber), _
        '    String.Format("-dLastPage={0}", pageNumber), _
        '    String.Format("-sOutputFile={0}", outputImgPath), _
        '    "-f", _
        '    pdfPath _
        '    }

        Dim args() As String = { _
            "-dNOPAUSE", _
            "-dBATCH", _
            "-sDEVICE=png16m", _
            String.Format("-dFirstPage={0}", pageNumber), _
            String.Format("-dLastPage={0}", pageNumber), _
            String.Format("-sOutputFile={0}", outputImgPath), _
            Replace(pdfPath, "\", "/") _
            }

        If GhostscriptDllLib.RunGS(args) Then
            If File.Exists(outputImgPath) Then
                objFileStream = New FileStream(outputImgPath, FileMode.Open)
                Dim length As Int32 = objFileStream.Length
                Dim bytes(length) As Byte
                objFileStream.Read(bytes, 0, length)
                objFileStream.Close()

                objMemoryStream = New MemoryStream(bytes, False)
                objImages.Add(Image.FromStream(objMemoryStream))

                File.Delete(outputImgPath)
            Else
                Throw New InvalidOperationException("Erro ao converter páginas do PDF em imagens PNG")
            End If
        Else
            Throw New InvalidOperationException("Erro ao converter páginas do PDF em imagens PNG")
        End If

    Next

    Return CType(objImages.ToArray(GetType(Image)), Image())

End Function
Community
  • 1
  • 1
Soriano
  • 103
  • 3