2015-11-03 94 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