使用PDFsharp将服务器端图像流转为PDF时解码错误问题咨询
问题根源
你遇到的是PDFsharp 1.50版本的固有特性:内存中创建的带图像的PdfDocument对象,只有调用Save方法完成序列化后,图像数据才会被完整嵌入到PDF结构中。你之前保存本地再读取能正常运行,就是因为Save操作触发了图像资源的最终写入逻辑,直接返回未执行Save的内存PdfDocument对象时,图像数据块是残缺的,所以打开PDF时会报解码错误。
可行解决方案
无需读写本地磁盘,使用内存流作为中转完成Save和重载流程即可,完全适配服务器无文件读写权限的场景,修改后代码如下:
private PdfDocument openImageFromByteArray(byte[] ImageStream) { MemoryStream imgStream = new MemoryStream(ImageStream); PdfDocument tempDoc = new PdfDocument(); tempDoc.Pages.Add(new PdfPage()); // 主动释放绘图和图像对象,避免服务器环境资源泄漏 using (XGraphics xgr = XGraphics.FromPdfPage(tempDoc.Pages[0])) using (XImage img = XImage.FromStream(imgStream)) { xgr.DrawImage(img, 0, 0); } // 内存流作为中转,替代本地文件完成序列化 MemoryStream tempBuffer = new MemoryStream(); // 第二个参数设为false,保存后不关闭流,方便后续读取 tempDoc.Save(tempBuffer, false); // 重置流指针到起始位置 tempBuffer.Position = 0; // 加载完成全量序列化的PDF文档后返回 PdfDocument OutputDocument = PdfReader.Open(tempBuffer, PdfDocumentOpenMode.Import); return OutputDocument; }
补充优化建议
- 如果后续需要对返回的PdfDocument做内容修改,将
PdfDocumentOpenMode.Import改为PdfDocumentOpenMode.Modify即可。 - 如果你的场景是直接生成PDF文件供下载/接口返回,无需返回PdfDocument对象,可以简化代码省去二次加载步骤,性能更好:
// 直接返回PDF字节数组的简化实现 private byte[] GeneratePdfWithImage(byte[] ImageStream) { MemoryStream imgStream = new MemoryStream(ImageStream); PdfDocument tempDoc = new PdfDocument(); tempDoc.Pages.Add(new PdfPage()); using (XGraphics xgr = XGraphics.FromPdfPage(tempDoc.Pages[0])) using (XImage img = XImage.FromStream(imgStream)) { // 可根据需要调整图片绘制的位置、宽高参数 xgr.DrawImage(img, 0, 0); } MemoryStream outputStream = new MemoryStream(); tempDoc.Save(outputStream); tempDoc.Close(); return outputStream.ToArray(); }
内容的提问来源于stack exchange,提问作者Drake
相关产品推荐
相关产品推荐

