Home > Blockchain >  PDFsharp/MigraDoc Add background images to pages
PDFsharp/MigraDoc Add background images to pages

Time:03-12

GOAL

To open an existing PDF file with multiple pages and add background image to all pages. (Optionally the background image of the first page differs from the others)

In my current implementation (I use .NET 6 and PDFsharp btw.) I add the image to each page, which increases the size of the file dependent on the number of pages.

QUESTION

Is there a way in PDFsharp/MigraDoc to embed a background image only once into the document and then reference it for each page?

CODE

Both PDF document and the image come from a database as byte arrays.

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();
}

SOLUTION

Rewriting the method above according to accepted answer, solved my problem:

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);
}

CodePudding user response:

With PDFsharp and MigraDoc this optimization is done automatically if you use them as intended.

Load the image once with PDFsharp and add it to as many pages as you like, there will be only one copy of the image in the document.

  • Related