How to add images without a linebreak (for background images)

I’m trying to generate a word/pdf document that contains 2 images: one full page background image and one table background image. I’ve added the background image in the footer and this works as expected. But for the header image I can’t add it in the header because it is then displayed behind the background image (only in pdf, not in word. Even when adding the header image last). To fix this I’ve just added the header image with a floating layout in a paragraph to the start of the section. This works almost as wanted, only because of the paragraph there now is a linebreak on top of the page, which pushes all content down.

My question is: how to add images without a linebreak, or how to add background images in a different way?

Currently I add the header image like this:

var headerPicture = new Picture(document, exportDto.HeaderFill.ImageUrl);

var pictureSize = new Size(section.PageSetup.PageWidth, 70);

var headerImageLayout = new FloatingLayout(
    new HorizontalPosition(15, LengthUnit.Point, HorizontalPositionAnchor.Page),
    new VerticalPosition(15, LengthUnit.Point, VerticalPositionAnchor.Page),
    pictureSize)
{
    WrappingStyle = TextWrappingStyle.BehindText,
    EffectPadding = Padding.None
};

headerPicture.Layout = headerImageLayout;

var headerParagraph = new Paragraph(document, headerPicture)
{
    ParagraphFormat =
    {
        SpaceAfter = 0,
        SpaceBefore = 0
    }
};

section.Blocks.Add(headerParagraph);

Hi Joren,

Where are you adding the footer image?

I tried adding the header image into the document’s body (like you did) and added a footer image into the document’s footer.
I was unable to reproduce your issue when doing this:

var document = DocumentModel.Load("input.docx");
var section = document.Sections[0];

// Header picture added to the body.
var headerPicture = new Picture(document, "header.png");
var pictureSize = new Size(section.PageSetup.PageWidth, 70);
var headerImageLayout = new FloatingLayout(
    new HorizontalPosition(15, LengthUnit.Point, HorizontalPositionAnchor.Page),
    new VerticalPosition(15, LengthUnit.Point, VerticalPositionAnchor.Page),
    pictureSize)
{
    WrappingStyle = TextWrappingStyle.BehindText,
    EffectPadding = Padding.None
};

headerPicture.Layout = headerImageLayout;
var headerParagraph = new Paragraph(document, headerPicture)
{
    ParagraphFormat =
    {
        SpaceAfter = 0,
        SpaceBefore = 0
    }
};

section.Blocks.Add(headerParagraph);

// Footer picture added to the footer.
var footer = section.HeadersFooters.GetOrAdd(HeaderFooterType.FooterDefault);
var footerPictureSize = new Size(section.PageSetup.PageWidth, section.PageSetup.PageHeight);
var footerPictureLayout = new FloatingLayout(
    new HorizontalPosition(0, LengthUnit.Point, HorizontalPositionAnchor.Page),
    new VerticalPosition(0, LengthUnit.Point, VerticalPositionAnchor.Page),
    footerPictureSize)
{
    WrappingStyle = TextWrappingStyle.BehindText,
    EffectPadding = Padding.None
};

var footerPicture = new Picture(document, "footer.png");
footerPicture.Layout = footerPictureLayout;

footer.Blocks.Add(new Paragraph(document, footerPicture));

document.Save("output.docx");
document.Save("output.pdf");

Regards,
Mario

I’m adding the footer like this:

private static void SetBackgroundImageIfNeeded(DocumentModel document, Section section, HeaderFooter footer, ActivityCalendarExportDto exportDto)
{
    if (exportDto.BackGroundFill?.ImageUrl == null)
    {
        return;
    }

    _backgroundImage ??= new Picture(document, exportDto.BackGroundFill.ImageUrl);
    var pictureSize = new Size(section.PageSetup.PageWidth, section.PageSetup.PageHeight);

    var headerImageLayout = new FloatingLayout(
        new HorizontalPosition(HorizontalPositionType.Left, HorizontalPositionAnchor.Page),
        new VerticalPosition(VerticalPositionType.Top, VerticalPositionAnchor.Page),
        pictureSize)
    {
        WrappingStyle = TextWrappingStyle.BehindText
    };

    _backgroundImage.Layout = headerImageLayout;
    footer.Blocks.Add(new Paragraph(document, _backgroundImage.Clone())); // footer = set to footer
}

If I then add the header image in a HeaderFooter element after I added the footer then the header image is not displayed in the pdf export because it is placed behind the background image in the footer. While converting the same documentModel to a word document does display the header before the word document. But this is not my main issue, this might already be fixed in newer version since I still use the 35.0.1659 version.

My biggest issue that I can’t seem to work arround is that when I add an image as a background for a certain element (like a table in most cases), then I have to add this image in a block element. But when I add an image in a Paragraph this will cause a linebreak. So even when the image is positioned absolute and behind elements it will still cause some layout changes because of the linebreak.

Is there any way to add an image without causing a linebreak?

I see now, so you don’t actually have this:

section.Blocks.Add(headerParagraph);

You have something like this instead:

var header = section.HeadersFooters.GetOrAdd(HeaderFooterType.HeaderDefault);
header.Blocks.Add(headerParagraph);

I tried adding images to both the header and footer, and I got the footer image overlapping the header image. The same is true for both DOCX and PDF output files.

If you’re getting a different result, please send us a small Visual Studio project that reproduces your issue so we can investigate it.

But when I add an image in a Paragraph this will cause a linebreak.

A Picture is an inline element that you can add to a new or to an existing Paragraph element.
What you probably want to do is add it to an existing paragraph.
For example:

// I'm getting the first paragraph in the document's body.
var paragraph = document.Sections[0].Blocks.OfType<Paragraph>().First();
paragraph.Inlines.Add(picture);

Retrieving the existing paragraph object will depend on your context. Can you tell me more about that so I can help you retrieve it?