MemoryStream 无法写入其他 MemoryStream

问题描述

一个内存流写入另一个内存流时遇到问题。 我正在使用 NuGet 包将 PDF 转换为 png。我需要将图像保存为 base64 字符串。 当我读入 pdf 时,它会正确创建具有正确预期页数的 pdf 对象。 在我将 pdf 保存到内存流后,该流有一个长度(大概是正确的,但现在尝试创建测试验证)。 在我通过复制到另一个流将流发送到它应该转换的位置后,另一个流永远没有任何数据。 我尝试了以下两种方法,一种更复杂,另一种基于我在此处找到的主题的简短而甜蜜的方法

我无法让我的内存流相互写入。

这是我的课

class pdf
{
    string localPath = @"C:\_Temp\MyForm.pdf";

    public pdf()
    {
        var base64String = GenerateSampleFormBase64(localPath);

        using(StreamWriter sw = new StreamWriter(@"C:\_Temp\log.txt"))
        {
            sw.WriteLine(base64String);
            sw.Flush();
        }

    }

    private static string GenerateSampleFormBase64(string path)
    {
        PdfDocument pdf = new PdfDocument(path);

        MemoryStream msPdf = new MemoryStream();
        pdf.Save(msPdf);

        var x = ConvertpdfpageToPng(msPdf);
        return Convert.ToBase64String(x);

    }

    static byte[] ConvertpdfpageToPng(MemoryStream msPng64)
    {
        // msPng64 length is 473923

        string base64;
        using(MemoryStream msPng = new MemoryStream(100))
        {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while((bytesRead = msPng64.Read(buffer,buffer.Length)) > 0)
            {
                msPng.Write(buffer,bytesRead);
            }

            // msPng is always length 0
            base64 = Convert.ToBase64String(msPng.GetBuffer(),(int)msPng.Length);
            byte[] raw = Convert.FromBase64String(base64);

            if(raw.Length > 0)
                return raw;
            else
                throw new Exception("Failed to write to memory stream.");
        }
    }

    // This also did not work
    public static string ConvertToBase64(MemoryStream stream)
    {
        byte[] bytes;
        using(var memoryStream = new MemoryStream(100))
        {
            stream.copyTo(memoryStream);
            bytes = memoryStream.ToArray();
        }

        return Convert.ToBase64String(bytes);
    }
}

解决方法

您使用 PdfDocument.Save() 方法,但它保存的是 PDF,而不是 PNG。您需要改用 PdfPage.Save。此示例代码显示了如何为 PDF 文档的第一页生成 Base64 格式的 PNG 图像:

using (var pdf = new PdfDocument(path))
{
    PdfDrawOptions options = PdfDrawOptions.Create();
    options.BackgroundColor = new PdfRgbColor(255,255,255);
    options.Compression = ImageCompressionOptions.CreatePng();

    string base64 = ConvertPdfPageToBase64Png(pdf.Pages[0],options);
    File.WriteAllText("page0_base64.txt",base64);
}

private static string ConvertPdfPageToBase64Png(PdfPage page,PdfDrawOptions options)
{
    using (var stream = new MemoryStream())
    {
        page.Save(stream,options);
        return Convert.ToBase64String(stream.GetBuffer(),(int)stream.Length);
    }
}