2016-11-04 2 views
3

Windows 8.1 Pro, Visual Studio 2015 Update 3, C#, .NET Framework 4.5. Ghostscript.NET (последний), GhostScript 9.20.C# .NET «Параметр недопустим», когда изображение в использовании оператора

Я конвертирую 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.

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

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

Я не нашел многого в этой теме, когда искал информацию. Я нашел один other StackOverflow post о том, кто использует графический объект в операторе using с той же ошибкой. Интересно, есть ли отношения. Я также отмечаю, что I should be using Dispose(), но это, кажется, вызывает проблему, и мне нужно, чтобы это работало.

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

Метод: public void Run(string str) ул является "Page pdfshowpage_init pdfshowpage_finish"

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

Вы нашли ответ на эту проблему, я тоже сталкиваюсь с подобной проблемой. – Puvi

ответ

0

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

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

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

Смежные вопросы