我正在使用Ghostscript.NET,一个方便的C#包装器,用于Ghostscript功能。我从客户端发送了一批PDF,以便在ASP .NET WebAPI服务器上转换为图像并返回给客户端。
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 :(得分: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);
}
看起来您没有保存文件。
我仍然在努力获得与此类似的东西,以便在我的最后工作。目前,我有两种方法可以尝试,先使用 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);
}
}
}
这会让你到任何地方吗?
答案 1 :(得分:0)
您不必在同一GhostscriptRasterizer实例上光栅化所有页面。在每页上使用一次性光栅化器,并在“列表图像”或“列表字节[]”中收集结果。 结果示例Jpeg编码的字节数组列表。
List<byte[]> result = new List<byte[]>();
for (int i = 1; i <= pdfPagesCount; i++)
{
using (var pageRasterizer = new GhostscriptRasterizer())
{
pageRasterizer.Open(stream, gsVersion, true);
using (Image tempImage = pageRasterizer.GetPage(dpiX, dpiY, i))
{
var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == System.Drawing.Imaging.ImageFormat.Jpeg.Guid);
var encoderParams = new EncoderParameters() { Param = new[] { new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 95L) } };
using (MemoryStream memoryStream = new MemoryStream())
{
tempImage.Save(memoryStream, encoder, encoderParams);
result.Add(memoryStream.ToArray());
}
}
}
}
如果您不知道PDF中的页数,则可以一次调用光栅化程序,并获取PageCount属性。