2013-06-28 3 views
2

Я работаю над решением, где я могу конвертировать PDF-файлы в изображения. Я использую следующий пример из CodeProject: http://www.codeproject.com/Articles/317700/Convert-a-PDF-into-a-series-of-images-using-Csharp?msg=4134859#xx4134859xxConvert PDF to Image Batch

теперь я попытался с помощью следующего кода, чтобы генерировать из более чем 1000 файлов PDF новых изображений:

using Cyotek.GhostScript; 
using Cyotek.GhostScript.PdfConversion; 
using System; 
using System.Collections.Generic; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace RefClass_PDF2Image 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string outputPath = Properties.Settings.Default.outputPath; 
      string pdfPath = Properties.Settings.Default.pdfPath; 

      if (!Directory.Exists(outputPath)) 
      { 
       Console.WriteLine("Der angegebene Pfad " + outputPath + " für den Export wurde nicht gefunden. Bitte ändern Sie den Pfad (outputPath) in der App.Config Datei."); 
       return; 
      } 
      else 
      { 
       Console.WriteLine("Output Pfad: " + outputPath + " gefunden."); 
      } 

      if (!Directory.Exists(pdfPath)) 
      { 
       Console.WriteLine("Der angegebene Pfad " + pdfPath + " zu den PDF Zeichnungen wurde nicht gefunden. Bitte ändern Sie den Pfad (pdfPath) in der App.Config Datei."); 
       return; 
      } 
      else 
      { 
       Console.WriteLine("PDF Pfad: " + pdfPath + " gefunden."); 
      } 


      Pdf2ImageSettings settings = GetPDFSettings(); 

      DateTime start = DateTime.Now; 
      TimeSpan span; 

      Console.WriteLine(""); 
      Console.WriteLine("Extraktion der PDF Zeichnungen wird gestartet: " + start.ToShortTimeString()); 
      Console.WriteLine(""); 

      DirectoryInfo diretoryInfo = new DirectoryInfo(pdfPath); 
      DirectoryInfo[] directories = diretoryInfo.GetDirectories(); 

      Console.WriteLine(""); 
      Console.WriteLine("Es wurden " + directories.Length + " verschiedende Verzeichnisse gefunden."); 
      Console.WriteLine(""); 

      List<string> filenamesPDF = Directory.GetFiles(pdfPath, "*.pdf*", SearchOption.AllDirectories).Select(x => Path.GetFullPath(x)).ToList(); 
      List<string> filenamesOutput = Directory.GetFiles(outputPath, "*.*", SearchOption.AllDirectories).Select(x => Path.GetFullPath(x)).ToList(); 

      Console.WriteLine(""); 
      Console.WriteLine("Es wurden " + filenamesPDF.Count + " verschiedende PDF Zeichnungen gefunden."); 
      Console.WriteLine(""); 

      List<string> newFileNames = new List<string>(); 
      int cutLength = pdfPath.Length; 


      for (int i = 0; i < filenamesPDF.Count; i++) 
      { 
       string temp = filenamesPDF[i].Remove(0, cutLength); 
       temp = outputPath + temp; 
       temp = temp.Replace("pdf", "jpg"); 
       newFileNames.Add(temp); 
      } 

      for (int i = 0; i < filenamesPDF.Count; i++) 
      { 
       FileInfo fi = new FileInfo(newFileNames[i]); 
       if (!fi.Exists) 
       { 
        if (!Directory.Exists(fi.DirectoryName)) 
        { 
         Directory.CreateDirectory(fi.DirectoryName); 
        } 

        Bitmap firstPage = new Pdf2Image(filenamesPDF[i], settings).GetImage(); 
        firstPage.Save(newFileNames[i], System.Drawing.Imaging.ImageFormat.Jpeg); 
        firstPage.Dispose(); 
       } 

       //if (i % 20 == 0) 
       //{ 
       // GC.Collect(); 
       // GC.WaitForPendingFinalizers(); 
       //} 
      } 


      Console.ReadLine(); 
     } 

     private static Pdf2ImageSettings GetPDFSettings() 
     { 
      Pdf2ImageSettings settings; 
      settings = new Pdf2ImageSettings(); 
      settings.AntiAliasMode = AntiAliasMode.Medium; 
      settings.Dpi = 150; 
      settings.GridFitMode = GridFitMode.Topological; 
      settings.ImageFormat = ImageFormat.Png24; 
      settings.TrimMode = PdfTrimMode.CropBox; 
      return settings; 
     } 
    } 
} 

, к сожалению, я всегда получаю в pdf2image. cs исключение из памяти. здесь код:

public Bitmap GetImage(int pageNumber) 
{ 
    Bitmap result; 
    string workFile; 

    //if (pageNumber < 1 || pageNumber > this.PageCount) 
    // throw new ArgumentException("Page number is out of bounds", "pageNumber"); 

    if (pageNumber < 1) 
     throw new ArgumentException("Page number is out of bounds", "pageNumber"); 

    workFile = Path.GetTempFileName(); 

    try 
    { 
    this.ConvertPdfPageToImage(workFile, pageNumber); 
    using (FileStream stream = new FileStream(workFile, FileMode.Open, FileAccess.Read)) 
    { 
     result = new Bitmap(stream); // --->>> here is the out of memory exception 
     stream.Close(); 
     stream.Dispose(); 
    } 

    } 
    finally 
    { 
    File.Delete(workFile); 
    } 

    return result; 
} 

Как исправить это, чтобы избежать этого исключения?

спасибо за любую помощь, TRO

+0

распоряжаться растровым изображением – Sayse

+0

да, вот что я делаю: firstPage.Dispose(); – tro

ответ

2

Не знаю, действительно ли это того стоит, но кажется, что вы можете делать то, что хотите, не имея растрового изображения посередине. PdfToImage имеет в этом коде код:

public void ConvertPdfPageToImage(string outputFileName, int pageNumber) 
{ 
    if (pageNumber < 1 || pageNumber > this.PageCount) 
    throw new ArgumentException("Page number is out of bounds", "pageNumber"); 

    using (GhostScriptAPI api = new GhostScriptAPI()) 
    api.Execute(this.GetConversionArguments(this._pdfFileName, outputFileName, pageNumber, this.PdfPassword, this.Settings)); 
} 

который записывает файл для вас, где вы хотите. Почему бы просто не вызвать этот метод напрямую, вместо того, чтобы снова прочитать изображение и записать его обратно?

+0

отлично! Это именно то, что я ищу! – tro

2

Это не может быть ответ на ваш вопрос прямо, но все еще может быть полезным: Imagemagick обеспечивает простой способ создания изображений из PDF-файлов в пакетном режиме

Single файл в формате PDF многие пробежка:

convert -geometry 1024x768 -density 200 -colorspace RGB test.pdf +adjoin test_%0d.jpg 

или если вы хотите обработать много файлов PDF:

mogrify -format jpg -alpha off -density 150 -quality 80 -resize 768 -unsharp 1.5 *.pdf 

(настройки, очевидно, должны быть адаптированы к вашим потребностям :))

Чтобы сделать это программно в C# можно использовать .NET ImageMagick обертку http://imagemagick.codeplex.com

+0

не совсем то, что я ищу, спасибо – tro

2

Добавить используя для растрового изображения в результате

using (FileStream stream = new FileStream(workFile, FileMode.Open, FileAccess.Read)) 
using (Bitmap result = new Bitmap(stream)) 
{ 
... 
} 
+0

Это решение выглядит более элегантно, чем просто распоряжаться. – Malhotra

+0

не работал в моем случае :-( – tro

+0

** Использование ** завершает закрытый блок в попытке/наконец, что вызывает ** Dispose ** в блоке finally, что гарантирует, что ** Dispose ** будет вызываться, даже если возникает исключение. [link] (http://stackoverflow.com/questions/10984336/net-using-using-blocks-vs-calling-dispose) – Adam