UglyToad / PdfPig

Read and extract text and other content from PDFs in C# (port of PDFBox)
https://github.com/UglyToad/PdfPig/wiki
Apache License 2.0
1.73k stars 241 forks source link

insert image into pdf #617

Closed ghost closed 1 year ago

ghost commented 1 year ago

Hi

I'm looking for a code example that inserts an image (jpg or png) into a pdf. It should keep the aspect ratio of the image

Thanks

JanRomero commented 1 year ago

hi. this will result in a portrait A4 page with a 4:3 image horizontally centered 2.5cm from the edges somewhere in the top half of the page.

using UglyToad.PdfPig.Writer;
using UglyToad.PdfPig.Content;
using UglyToad.PdfPig.Core;

internal class Program
{
    static async Task Main(string[] args)
    {
        using (var builder = new PdfDocumentBuilder())
        using (var imgstream = new FileStream(@"C:\temp\mypic.jpg", FileMode.Open))
        {
            var page = builder.AddPage(PageSize.A4, true);

            //rectangles are bottom left X, bottom left Y, top right X, top right Y.
            //you have to calculate the aspect ratio yourself.
            //in this case it's 4:3.
            var imgX = cmToPdfUnits(2.5);
            var imgY = cmToPdfUnits(14);
            var imgWidth = cmToPdfUnits(16);
            var imgHeight = cmToPdfUnits(12);
            page.AddJpeg(imgstream, new PdfRectangle(imgX, imgY, imgX + imgWidth, imgY + imgHeight));

            await File.WriteAllBytesAsync(@"C:\temp\mypiconapage.pdf", builder.Build());
        }
    }

    private static double cmToPdfUnits(double cm) => cm / 2.54 * 72;
}
ghost commented 1 year ago
JanRomero commented 1 year ago
using (var builder = new PdfDocumentBuilder())
using (var imgstream = new FileStream(@"C:\temp\mypic.jpg", FileMode.Open))
{
    var page = builder.AddPage(PageSize.A4, false);

    //add image invisibly just so we can get the size
    var img = page.AddJpeg(imgstream, new PdfRectangle(0,0,0,0));

    var imgAspect = (double)img.Width / img.Height;
    var pageAspect = page.PageSize.Width / page.PageSize.Height;

    //make image cover the entire page by adjusting the size and positioning it so it’s centered
    if (pageAspect < imgAspect)
    {
        var fillHeight = page.PageSize.Height;
        var fillWidth = fillHeight * imgAspect;
        var xpos = (page.PageSize.Width - fillWidth) / 2;
        page.AddImage(img, new PdfRectangle(xpos, 0, xpos + fillWidth, fillHeight));
    }
    else
    {
        var fillWidth = page.PageSize.Width;
        var fillHeight = fillWidth / imgAspect;
        var ypos = (page.PageSize.Height - fillHeight) / 2;
        page.AddImage(img, new PdfRectangle(0, ypos, fillWidth, ypos + fillHeight));
    }

    await File.WriteAllBytesAsync(@"C:\temp\mypiconapage.pdf", builder.Build());
}
ghost commented 1 year ago

Do you maybe want to add a method to pdfpig that does this and we just can call it by passing an image file to it? So for maximizing an image to fit the page but keep the aspect ratio. I think the solution above would not be easy to find by beginners like me.

EliotJones commented 1 year ago

Thanks @JanRomero for documenting the answer here.

The suggestion by the issue author is reasonable but falls into the bucket of document creation enhancements I personally won't be able to get to. Closing as won't do for now.