Azure Function中PdfSharp转PNG为PDF遇MemoryStream缓冲区错误求助
错误原因
用new MemoryStream(pngBytes)创建的流处于只读状态,且CanGetBuffer属性为false。PdfSharp的XImage.FromStream方法内部会调用MemoryStream.GetBuffer()直接读取底层字节数组,但只读流不允许该操作,因此抛出异常。Azure Functions的沙箱环境会严格执行这类限制,所以更容易触发该问题。
修复方案
提供两种可靠的修复方式:
方案1:使用可写的MemoryStream重载
通过MemoryStream的重载构造函数,创建允许写入和访问缓冲区的流,同时重置流位置到起始处:
private static byte[] ConvertPngBytesToPdfBytes(byte[] pngBytes) { // 构造可写、允许访问缓冲区的MemoryStream using (var imageStream = new MemoryStream(pngBytes, 0, pngBytes.Length, true, true)) { imageStream.Position = 0; var image = XImage.FromStream(imageStream); using var pdfStream = new MemoryStream(); var document = new PdfDocument(); var page = document.AddPage(); page.Width = XUnit.FromPoint(image.PixelWidth * 72 / image.HorizontalResolution); page.Height = XUnit.FromPoint(image.PixelHeight * 72 / image.VerticalResolution); using (var gfx = XGraphics.FromPdfPage(page)) { gfx.DrawImage(image, 0, 0, page.Width.Point, page.Height.Point); } document.Save(pdfStream, false); return pdfStream.ToArray(); } }
方案2:将字节数组写入空的MemoryStream
先创建空的可写MemoryStream,再把PNG字节数组写入其中,最后重置流位置:
private static byte[] ConvertPngBytesToPdfBytes(byte[] pngBytes) { using (var imageStream = new MemoryStream()) { imageStream.Write(pngBytes, 0, pngBytes.Length); imageStream.Position = 0; // 重置到流开头,确保能读取完整内容 var image = XImage.FromStream(imageStream); using var pdfStream = new MemoryStream(); var document = new PdfDocument(); var page = document.AddPage(); page.Width = XUnit.FromPoint(image.PixelWidth * 72 / image.HorizontalResolution); page.Height = XUnit.FromPoint(image.PixelHeight * 72 / image.VerticalResolution); using (var gfx = XGraphics.FromPdfPage(page)) { gfx.DrawImage(image, 0, 0, page.Width.Point, page.Height.Point); } document.Save(pdfStream, false); return pdfStream.ToArray(); } }
补充说明
- 两种方案都解决了只读流无法访问缓冲区的问题,符合PdfSharp的内部调用要求。
- 在Azure Functions环境中更推荐方案2,逻辑更直观,无需依赖构造函数的重载参数细节。
内容的提问来源于stack exchange,提问作者f_olivere
相关产品推荐
相关产品推荐

