3

Windows 8.1 专业版、Visual Studio 2015 更新 3、C#、.NET Framework 4.5。Ghostscript.NET(最新),GhostScript 9.20。

我正在将 PDF 转换为 PDF。哈。好吧,我正在制作无法编辑且质量较低的“可编辑”PDF“硬”PDF。过程是我获取可编辑的 PDF,将其保存为 x 页的 PNG 文件,将这些 PNG 文件转换为多页 TIFF,然后将多页 TIFF 转换为我需要的 PDF。

这与 Visual Studio 2012(GhostScript .NET 和 GS 9.10 的一个早期版本)配合得很好。

public static Tuple<string, List<string>> CreatePNGFromPDF(string inputFile, string outputfile)
{
    Tuple<string, List<string>> t = null;
    List<string> fileList = new List<string>();
    string message = "Success";
    string outputFileName = string.Empty;

    int desired_x_dpi = 96;
    int desired_y_dpi = 96;

    try
    {
        using (GhostscriptViewer gsViewer = new GhostscriptViewer())
        {
            gsViewer.Open(inputFile);
            using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
            {
                for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
                {
                    using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))
                    {
                        outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
                        img.Save(outputFileName, ImageFormat.Png);
                        if (!fileList.Contains(outputFileName))
                        {
                            fileList.Add(outputFileName);
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        message = ex.Message;
    }

    t = new Tuple<string, List<string>>(message, fileList);
    return t;
}

现在这行失败了:

using (System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber))

处理第二页时。第一页工作正常。

我下载了 GhostScript.NET 的源代码,将其添加到我的解决方案中,进行了调试等,并花了很长时间试图弄清楚这一点。

然后我决定分离出这些功能,并让我在一个简单的控制台应用程序中进一步检查最低限度的功能:

static void Main(string[] args)
{
    int xDpi = 96;
    int yDpi = 96;

    string pdfFile = @"Inputfilenamehere.pdf";
    GhostscriptVersionInfo gsVersionInfo = GhostscriptVersionInfo.GetLastInstalledVersion(GhostscriptLicense.GPL | GhostscriptLicense.AFPL, GhostscriptLicense.GPL);
    List<GhostscriptVersionInfo> gsVersionInfoList = GhostscriptVersionInfo.GetInstalledVersions(GhostscriptLicense.GPL | GhostscriptLicense.AFPL);

    try
    {
        using (GhostscriptViewer gsViewer = new GhostscriptViewer())
        {
            gsViewer.Open(pdfFile);
            using (GhostscriptRasterizer gsRasterizer = new GhostscriptRasterizer(gsViewer))
            {
                int pageCount = gsRasterizer.PageCount;

                for (int i = 0; i < pageCount; i++)
                {
                    Image img = gsRasterizer.GetPage(xDpi, yDpi, i + 1);
                }
            }
        }
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

瞧,没问题。不同之处在于我没有在声明中声明我的图像using

我总是努力成为一个优秀的男孩开发人员,并在类实现时使用 using 语句IDisposable

因此,我删除了 using 并获得了我一直想要的低质量 PDF。我现在的生活很好。

        using (GhostscriptViewer gsViewer = new GhostscriptViewer())
        {
            gsViewer.Open(inputFile);
            using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer(gsViewer))
            {
                for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
                {
                    System.Drawing.Image img = rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber);

                    outputFileName = outputfile.Replace(".png", string.Empty) + "_page_" + pageNumber.ToString() + ".png";
                    img.Save(outputFileName, ImageFormat.Png);
                    if (!fileList.Contains(outputFileName))
                    {
                        fileList.Add(outputFileName);
                    }
                }
            }
        }

请注意,如果我img.Dispose()for循环结束时调用,我会再次收到相同的错误!

我最好的猜测是我的问题不是 GhostScript 或 GhostScript.NET 问题。如果类实现,我是否坚持盲目使用“使用”语句IDisposable?我一直明白,最好的做法是IDisposableusing声明来包装任何实现以放弃泄漏等。

因此,我的问题是:任何想法为什么我System.Drawing.Image在语句中初始化类时得到“参数无效”异常,但在我不初始化类using时却没有?我很想了解更多。

更好的是,如果有人知道我如何获得此功能并确保我正确处理我的对象,那将是最好的。

当我搜索信息时,我没有找到太多关于这个特定主题的信息。我确实找到了另一篇关于有人在 using 语句中使用图形对象的StackOverflow 帖子,但出现了相同的错误。我想知道有没有关系。我还注意到我应该使用 Dispose(),但这似乎是导致问题的原因,我需要它来工作。

仅供参考,对于任何感兴趣的人,实际错误发生在 GhostScript.NET 代码中的 GhostscriptInterprester.cs 中:

方法:public void Run(string str) str是“页面pdfshowpage_init pdfshowpage_finish”

// GSAPI: run the string
int rc_run = _gs.gsapi_run_string(_gs_instance, str, 0, out exit_code);
4

1 回答 1

0

我至少找到了我失败的根本原因。我的 GhostscriptRasterizer 对象为高度点和宽度点设置了“0”值。

var rasterizer = new GhostscriptRasterizer();
rasterizer.CustomSwitches.Add("-dDEVICEWIDTHPOINTS=" + widthPoints);
rasterizer.CustomSwitches.Add("-dDEVICEHEIGHTPOINTS=" + heightPoints);

一旦我将高度和宽度都设置为有效的非零值,问题就得到了解决。

于 2017-05-24T20:05:10.890 回答