2015-11-03 54 views
3

我正在使用Ghostscript.NET,這是一個方便的Ghostscript功能的C#包裝器。我有一批從客戶端發送的PDF文件被轉換爲ASP .NET WebAPI服務器上的圖像並返回給客戶端。Ghostscript.NET光柵器內存不足

public static IEnumerable<Image> PdfToImagesGhostscript(byte[] binaryPdfData, int dpi) 
{ 
    List<Image> pagesAsImages = new List<Image>(); 

    GhostscriptVersionInfo gvi = new GhostscriptVersionInfo(AppDomain.CurrentDomain.BaseDirectory + @"\bin\gsdll32.dll"); 

    using (var pdfDataStream = new MemoryStream(binaryPdfData)) 
    using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer()) 
    { 
     rasterizer.Open(pdfDataStream, gvi, true); 

     for (int i = 1; i <= rasterizer.PageCount; i++) 
     { 
      Image pageAsImage = rasterizer.GetPage(dpi, dpi, i); // Out of Memory Exception on this line 
      pagesAsImages.Add(pageAsImage); 
     } 
    } 
    return pagesAsImages; 
} 

這通常工作正常(我通常使用500 dpi,我知道是高的,但即使降到300我可以重現此錯誤)。但是,如果我從客戶端提供很多PDF(例如,150頁的1頁PDF),它通常會遇到Ghostscript.NET Rasterizer中的「內存不足」異常。我該如何克服這一點?這應該通過?如果是這樣會如何工作?它有助於使用64位版本的GhostScript嗎?提前致謝。

+0

你可以在'add'後調用'pageAsImage'上的Dispose嗎?不,線程不會幫助解決這個內存問題。是的,在64位進程中運行可能會有所幫助。如果沒有這些幫助,那麼顯式調用'GC.Collect()'可能是必要的(儘管這真是一個糟糕的破解)。 –

+0

@ChrisO謝謝,但處置它使得它在返回的對象中無法訪問。當試圖使用64位DLL時,我得到這個錯誤「您正在使用原生Ghostscript庫(gsdll64.dll)在32位進程中爲64位系統編譯,您需要使用gsdll32.dll。」任何想法爲什麼這是一個32位的過程?我在Visual Studio 2015中通​​過調試運行ASP .NET WebAPI。 –

+3

'Tools |選項|項目和解決方案| Web項目|使用64位版本的IIS Express,但我沒有嘗試過VS2015。 –

回答

0

我是新來這個自己,在這裏尋找技術。

根據文檔here的例子中,它顯示了:

for (int page = 1; page <= _rasterizer.PageCount; page++) 
{ 
    var docName = String.Format("Page-{0}.pdf", page); 
    var pageFilePath = Path.Combine(outputPath, docName); 
    var pdf = _rasterizer.GetPage(desired_x_dpi, desired_y_dpi, pageNumber); 
    pdf.Save(pageFilePath); 
    pagesAsImages.Add(pdf); 
} 

看起來你是不是保存文件。

我仍在努力獲得與此相似的東西,以便在我的工作中也能夠工作。目前,我有2種方法,我要去嘗試,使用GhostscriptProcessor第一:

private static void GhostscriptNetProcess(String fileName, String outputPath) 
{ 
    var version = Ghostscript.NET.GhostscriptVersionInfo.GetLastInstalledVersion(); 
    var source = (fileName.IndexOf(' ') == -1) ? fileName : String.Format("\"{0}\"", fileName); 
    var gsArgs = new List<String>(); 
    gsArgs.Add("-q"); 
    gsArgs.Add("-dNOPAUSE"); 
    gsArgs.Add("-dNOPROMPT"); 
    gsArgs.Add("-sDEVICE=pdfwrite"); 
    gsArgs.Add(String.Format(@"-sOutputFile={0}", outputPath)); 
    gsArgs.Add(source); 
    var processor = new Ghostscript.NET.Processor.GhostscriptProcessor(version, false); 
    processor.Process(gsArgs.ToArray()); 
} 

下面這個版本與你相似,和我開始使用的,直到我開始尋找其他的代碼示例:

private static void GhostscriptNetRaster(String fileName, String outputPath) 
{ 
    var version = Ghostscript.NET.GhostscriptVersionInfo.GetLastInstalledVersion(); 
    using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer()) 
    { 
     rasterizer.Open(File.Open(fileName, FileMode.Open, FileAccess.Read), version, false); 
     for (int page = 0; page < rasterizer.PageCount; page++) 
     { 
      var img = rasterizer.GetPage(96, 96, page); 
      img.Save(outputPath); 
     } 
    } 
} 

這會讓你有什麼感覺嗎?

+0

我想從pdf文檔中獲得特定的頁面,第一次它可以,但是當我嘗試從該pdf文檔'內存不足'錯誤的另一個頁面轉換停止我。我試圖解決這個問題已經兩天了,差不多我嘗試了所有的解決方案,但沒有成功。任何幫助將非常感激。 – metmirr

+0

@metmirr - 這是一份合同工作,我不再擁有它的代碼。我已經工作的最好的代碼段在這裏發佈:https://stackoverflow.com/a/34770558/153923 – jp2code

+0

如果你有一個32位電腦或你的程序使用32位插件,你要去的最大尺寸能夠訪問的文件大小是2GB。 – jp2code