首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Ghostscript包装器VB.NET将PDF页面转换为PNG?

如何使用Ghostscript包装器VB.NET将PDF页面转换为PNG?
EN

Stack Overflow用户
提问于 2016-02-17 13:03:22
回答 2查看 1.8K关注 0票数 0

我正在尝试使用以下解决方案:Ghostscript Dll的简单VB.Net包装器将数字签名的PDF转换为PNG。对我也没用。我使用的是Ghostscript 9.18 32位。

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

代码语言:javascript
运行
复制
gsapi_init_with_args(InstanceHndl, NumArgs + 1, Args)

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

代码语言:javascript
运行
复制
If gsapi_new_instance(InstanceHndl, IntPtr.Zero) <> 0 Then
    Return False
    Exit Function
End If

gsapi_new_instance的返回值为-100:Ghostscript API -返回代码

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

我的参数序列:

代码语言:javascript
运行
复制
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建议我进行一些争论。所以,我把它拿去测试。

我的完整代码:

代码语言:javascript
运行
复制
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

呼叫者代码:

代码语言:javascript
运行
复制
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

我在命令行中测试这一点,以便:

代码语言:javascript
运行
复制
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被转换。命令行输出:

代码语言:javascript
运行
复制
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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-17 13:36:10

‘.’更多的信息通常被打印到stdout或stderr中,当然设置-dQUIET会抑制这其中的大部分.

由于您要返回-100,所以几乎可以肯定,您对Ghostscript的论点在某种程度上是不正确的。

在调试问题时,您应该做的第一件事就是尝试简化问题,因此删除所有您不需要的开关。

因此,首先要做的是删除-dQUIET,捕获所有stdout/stderr输出,并告诉我们它说了什么。

此外,请注意以下几点:

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

您还没有给出“resolucao”、“pageNumber”或“pdfPath”之类的值,因此无法知道这些值是否有效(或合理)。您为outputImgPath指定的路径相当长,包括反斜杠字符。我建议使用正斜杠'/‘代替,因为反斜杠用于开始转义,并且可以给出您可能不期望的结果。

您也使用过-dSAFER,您了解指定这一点的含义吗?如果没有,请移除,然后再试一次。

创建字符串'args‘时,将其打印出来。至少,这将给您提供一些您可以从命令行尝试的东西,并且可能意味着其他人有机会重现您的问题。

最后,请注意,Ghostscript是根据阿弗莱罗通用公共许可证分发的,请务必阅读许可证,并确保您符合其中所载的条款。

票数 0
EN

Stack Overflow用户

发布于 2016-02-17 20:49:06

为此,我修改了Ghostscript Dll的简单VB.Net包装器 CallBack:

代码语言:javascript
运行
复制
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输出转到 output 窗口的Visual 2003中。我将额外的“不必要”参数移除给Ghostscript,比如-dGraphicsAlphaBits。asp.net用户不访问Path.GetTempDir,因此,我需要一个不同的“临时”dir。

代码语言:javascript
运行
复制
'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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35457525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档