如何使用Ghostscript Wrapper VB.NET将PDF页面转换为PNG?

时间:2016-02-17 13:03:22

标签: asp.net vb.net pdf dllimport ghostscript

我正在尝试使用此解决方案将数字签名的PDF转换为PNG:Simple VB.Net Wrapper for Ghostscript Dll。它对我也不起作用。我正在使用Ghostscript 9.18 32位。

首先,源代码转到此部分的InOutErrCallBack方法:

gsapi_init_with_args(InstanceHndl, NumArgs + 1, Args)

当发生这种情况时,执行冻结。发生这种情况后,下一次对RunGS方法的调用在此部分中返回false:

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

gsapi_new_instance的返回值为-100: Ghostscript API - Return codes

gswin32.dll位于C:\ Windows \ System32和BIN项目文件夹中。

我的参数序列:

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 _
    }

更新

@kens建议我提出一些论点。所以,我删除它来测试。

我的完整代码:

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

来电者代码:

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

我在命令行中对此进行测试:

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

通过命令行转换pdf。命令行输出:

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>

2 个答案:

答案 0 :(得分:0)

-100只是'致命错误',即发生了非常糟糕的事情。更多信息通常打印到stdout或stderr,当然设置-dQUIET会抑制大部分内容....

因为你得到-100返回它几乎肯定是你的Ghostscript参数在某种程度上是不正确的。

调试问题时,您应该首先考虑的是尝试简化问题,因此请删除任何您不需要的开关。

所以要做的第一件事就是删除-dQUIET,捕获所有stdout / stderr输出并告诉我们它的内容。

除此之外,请注意以下事项:

您不需要'-f',因为该开关的唯一目的是终止您尚未使用的-c。

您没有给出'resolucao','pageNumber'或'pdfPath'等值,因此无法知道这些是否有效(或合理)。您为outputImgPath指定的路径非常长,并包含反斜杠字符。我会建议使用正斜杠'/',因为反斜杠用于开始转义并且可以给出你可能没想到的结果。

您还使用了-dSAFER,您是否了解指定此含义的含义?如果没有,请将其删除并重试。

创建字符串'args'后将其打印出来。至少这会给你一些你可以从命令行尝试的东西,也许意味着其他人有机会再现你的问题。

最后;请注意,Ghostscript是根据Affero通用公共许可证分发的,请务必阅读许可证并确保您遵守其中包含的条款。

答案 1 :(得分:0)

为了完成这项工作,我修改了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

这将Ghostscript输出写入输出窗口的Visual Studio 2003.我删除了Ghostscript的额外“不必要”参数,如-dGraphicsAlphaBits。 asp.net用户不访问Path.GetTempDir,因此,我需要一个不同的“临时”目录。

'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