C# .NET "Параметр недействителен", когда изображение в выражении using

Windows 8.1 Pro, 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,

Итак, я удалил использование использования и получил 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. Я тупица за то, что настаиваю на слепом использовании выражений "using", если класс реализует IDisposable? Я всегда понимал, что лучше всего оборачивать все, что реализует IDisposable с using заявление об отказе от утечек и т. д.

Отсюда мой вопрос: любые идеи, почему я получаю исключение "Параметр неверен" при инициализации System.Drawing.Image класс в пределах using заявление, но не тогда, когда я не? Я хотел бы понять это больше.

Еще лучше, если кто-нибудь знает, как я могу получить эту функциональность, а также убедиться, что я правильно избавляюсь от своего объекта, это было бы лучше.

Я не нашел много об этой конкретной теме, когда я искал информацию. Я нашел еще одну публикацию Stackru о том, что кто-то использует графический объект в операторе using с той же ошибкой. Интересно, есть ли отношения? Я также отмечаю, что я должен использовать Dispose (), но это, кажется, вызывает проблему, и мне нужно, чтобы это работало.

К вашему сведению, для тех, кто заинтересован, фактическая ошибка происходит здесь, в GhostscriptInterprester.cs в коде GhostScript .NET:

Метод: public void Run(string str) str is "Page pdfshowpage_init pdfshowpage_finish"

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

1 ответ

Я нашел основную причину моей неудачи, по крайней мере. Мой объект GhostscriptRasterizer имел значение '0', установленное для точек высоты и ширины.

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

Как только я установил для высоты и ширины правильное ненулевое значение, проблема была исправлена.

Другие вопросы по тегам