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 加载一次图像,并根据需要将其添加到任意多个页面,文档中将只有一个图像副本。
目标
打开包含多个页面的现有 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 加载一次图像,并根据需要将其添加到任意多个页面,文档中将只有一个图像副本。