PDFsharp/MigraDoc将背景图像添加到页面中



目标

打开具有多个页面的现有PDF文件并将背景图像添加到所有页面。(可选地,第一页的背景图像与其他页面不同(

在我当前的实现中(我使用.NET 6和PDFsharp btw.(,我将图像添加到每个页面,这会根据页面数量增加文件的大小。

问题

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加载图像一次,然后将其添加到任意多个页面,文档中只有一个图像副本。

最新更新