PDFsharp/MigraDoc 向页面添加背景图片

PDFsharp/MigraDoc Add background images to pages

目标

打开包含多个页面的现有 PDF 文件并为所有页面添加背景图像。 (可选的第一页背景图片与其他页面不同)

在我当前的实现中(顺便说一句,我使用 .NET 6 和 PDFsharp。)我将图像添加到每一页,这会根据页数增加文件的大小。

问题

在 PDFsharp/MigraDoc 中有没有一种方法可以将背景图像仅嵌入到文档中一次,然后在每个页面中引用它?

代码

PDF 文档和图像均以字节数组形式来自数据库。

public byte[] AddBackgroundImgToDocument(byte[] doc, byte[] imgFirstPage, byte[]? imgOtherPages=null)
{
    using var ms = new MemoryStream(doc);
    PdfDocument pdfDoc = PdfReader.Open(ms, PdfDocumentOpenMode.Modify);
    
    for (int i = 0; i < pdfDoc.PageCount; i++)
    {
        if(i > 0 && imgOtherPages != null && imgOtherPages.Length > 0)
            AddBackgroundImageFromByteArray(pdfDoc.Pages[i], imgOtherPages);
        else
            AddBackgroundImageFromByteArray(pdfDoc.Pages[i], imgFirstPage);

        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
    using var oms = new MemoryStream();
    pdfDoc.Save(oms);
    ms.Dispose();
    pdfDoc.Dispose();
    return oms.ToArray();
}

public void AddBackgroundImageFromByteArray(PdfPage page, byte[] imgfile)
{
    XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
    MemoryStream ms = new System.IO.MemoryStream(imgfile);
    ms.Position = 0;
    XImage image = XImage.FromStream(() => ms);
    gfx.DrawImage(image, 0, 0, page.Width, page.Height);
    ms.Dispose();
}

解决方案

根据接受的答案重写上面的方法,解决了我的问题:

public void AddBackgroundImageFromByteArray(PdfPage page, byte[] imgfile)
{
    if(!ximageLoaded)
    {
        MemoryStream ms = new System.IO.MemoryStream(imgfile);
        ms.Position = 0;
        backimg = XImage.FromStream(() => ms);
        ms.Dispose();
        ximageLoaded = true;
    }

    XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
    gfx.DrawImage(backimg, 0, 0, page.Width, page.Height);
}

如果您按预期使用 PDFsharp 和 MigraDoc,此优化会自动完成。

使用 PDFsharp 加载一次图像,并根据需要将其添加到任意多个页面,文档中将只有一个图像副本。