3

Windows 8.1 Pro、Visual Studio 2015 Update 3、C#、.NET Framework 4.5。Ghostscript.NET (最新)、GhostScript 9.20。

PDFをPDFに変換しています。はぁ。さて、私は「編集可能な」PDF「ハード」PDFを作成しています。これは編集できず、品質が低くなります。プロセスは、編集可能な PDF を取得し、PNG ファイルの X ページとして保存し、それらの PNG ファイルを複数ページの TIFF に変換してから、複数ページの TIFF を必要な PDF に変換することです。

これは、GhostScript .NET の 1 つ前のバージョンである Visual Studio 2012 と 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))

2ページ目を処理するとき。最初のページは問題なく動作します。

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

そのため、使用の使用を削除し、常に望んでいた低品質の 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. リークなどを避けるために、実装IDisposableするものをステートメントでラップすることがベストプラクティスであることを常に理解しています.using

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 に答える