C#使用PDFium无需转Bitmap从图片流创建PDF文档的方案咨询
解决方案
不需要将图片流强制转换为System.Drawing.Bitmap对象,PDFium C#提供了直接从原始图片字节加载的重载,可以跳过中间Bitmap转换步骤。
实现思路
- PDFium内置了PNG、JPG、BMP等主流图片格式的解析能力,
PdfImageObject.Create提供了直接接收图片字节数组的重载,不需要开发者手动做格式解码、绘图拷贝操作。 - 只需要将输入的图片流读取为字节数组,直接传入即可生成对应的PDF图片对象,减少不必要的性能开销,同时可以规避System.Drawing.Common在非Windows平台的兼容性问题。
优化后代码
public void GeneratePdfFromImageStream(List<Stream> imageStreams, String pdfSaveLocation = null) { int pageIndex = 0; // 初始化PDF库 PdfCommon.Initialize(); // 创建PDF文档 using (var doc = PdfDocument.CreateNew()) { foreach (var imageStream in imageStreams) { // 直接读取流为字节数组,无需转换System.Drawing.Bitmap using var ms = new MemoryStream(); imageStream.CopyTo(ms); var imageBytes = ms.ToArray(); // 直接从字节数组创建PDF图片对象 var imageObject = PdfImageObject.Create(doc, imageBytes, 0, imageBytes.Length); // 计算PDF页面尺寸:无严格DPI要求可直接用默认96,有DPI要求可单独解析图片头获取原始DPI,无需加载全量Bitmap var size = CalculateSize(imageObject.Width, imageObject.Height, 96, 96); // 插入页面并添加图片对象 doc.Pages.InsertPageAt(pageIndex, size); doc.Pages[pageIndex].PageObjects.Add(imageObject); imageObject.Matrix = new FS_MATRIX(size.Width, 0, 0, size.Height, 0, 0); doc.Pages[pageIndex].GenerateContent(); pageIndex++; } // 保存PDF:如果不需要落盘可调用doc.Save(Stream, SaveFlags)重载直接输出内存流对接后续API if (string.IsNullOrWhiteSpace(pdfSaveLocation)) doc.Save($"saved_{Guid.NewGuid().ToString()}.pdf", SaveFlags.NoIncremental); else doc.Save(pdfSaveLocation, SaveFlags.NoIncremental); } }
注意事项
- 该重载在Patagames.Pdf.Net 4.x及以上版本均支持,低版本需要先升级NuGet包。
- 如果业务需要严格匹配图片原始DPI计算PDF页面尺寸,可以单独解析图片文件头获取DPI信息,不用加载完整Bitmap,性能远高于全量解码图片。
内容的提问来源于stack exchange,提问作者Dangerous Dev
相关产品推荐
相关产品推荐

