0

I am attempting to append images to an existing PDF using the following.

public static byte[] Append(byte[] inputPdf, params Image[] images)
{
    var ms = new MemoryStream();
    ms.Write(inputPdf, 0, inputPdf.Length);
    ms.Seek(0, SeekOrigin.Begin);

    using (Document pdf = new Document(iTextSharp.text.PageSize.A4, 10, 10, 10, 10))
    using (PdfWriter writer = PdfWriter.GetInstance(pdf, ms))
    {
        pdf.Open();
        foreach (var image in images)
        {

            var result = pdf.NewPage();

            ImageFormat format = image.PixelFormat == PixelFormat.Format1bppIndexed
                || image.PixelFormat == PixelFormat.Format4bppIndexed
                || image.PixelFormat == PixelFormat.Format8bppIndexed
                ? ImageFormat.Tiff
                : ImageFormat.Jpeg;
            var pdfImage = iTextSharp.text.Image.GetInstance(image, format);
            pdfImage.Alignment = Element.ALIGN_CENTER;
            pdfImage.ScaleToFit(pdf.PageSize.Width, pdf.PageSize.Height);
            pdf.Add(pdfImage);
        }
        pdf.Close();
    }
    ms.Flush();
    return ms.GetBuffer();
}

The result value is not used, I was debugging it. The value is always true, so the add page is working.

The resulting PDF is the same size as the original, but is not readable. I get invalid root object errors when opening it.

Any suggestions?

Thanks

Jim
  • 14,952
  • 15
  • 80
  • 167
  • When working with an existing PDF you need to use a PdfStamper, see [How can I insert an image with iTextSharp in an existing PDF?](http://stackoverflow.com/questions/583629/how-can-i-insert-an-image-with-itextsharp-in-an-existing-pdf) – Chris Haas Apr 11 '13 at 13:02

2 Answers2

1

Method 1 (without PdfStamper)

using (var ms = new MemoryStream())
{
        var pdf = new PdfReader(inputPdf);
        var doc = new Document(pdf.GetPageSizeWithRotation(1));
        using (var writer = PdfWriter.GetInstance(doc, ms))
        {
            doc.Open();

            for (int page = 0; page < pdf.NumberOfPages; page++)
            {
                doc.SetPageSize(pdf.GetPageSizeWithRotation(page + 1));
                doc.NewPage();
                var pg = writer.GetImportedPage(pdf, page + 1);
                int rotation = pdf.GetPageRotation(page + 1);
                if (rotation == 90 || rotation == 270)
                    writer.DirectContent.AddTemplate(
                        pg, 0, -1f, 1f, 0, 0, pdf.GetPageSizeWithRotation(page).Height);
                else
                    writer.DirectContent.AddTemplate(pg, 1f, 0, 0, 1f, 0, 0);
            }
            foreach (var image in images)
            {
                doc.NewPage();

                ImageFormat format = image.PixelFormat == PixelFormat.Format1bppIndexed
                                     || image.PixelFormat == PixelFormat.Format4bppIndexed
                                     || image.PixelFormat == PixelFormat.Format8bppIndexed
                                         ? ImageFormat.Tiff
                                         : ImageFormat.Jpeg;
                var pdfImage = iTextSharp.text.Image.GetInstance(image, format);
                pdfImage.Alignment = Element.ALIGN_CENTER;
                pdfImage.ScaleToFit(doc.PageSize.Width - 10, doc.PageSize.Height - 10);
                doc.Add(pdfImage);
            }
            doc.Close();
            writer.Close();
        }
        ms.Flush();
        return ms.GetBuffer();
}

Method 2 (using PdfStamper)

var pdfReader = new PdfReader(inputPdf);
using (var ms = new MemoryStream())
{
        using (var stamp = new PdfStamper(pdfReader, ms))
        {
            foreach (var image in images)
            {
                var size = pdfReader.GetPageSize(1);
                var page = pdfReader.NumberOfPages + 1;
                stamp.InsertPage(page, pdfReader.GetPageSize(1));
                ImageFormat format = image.PixelFormat == PixelFormat.Format1bppIndexed
                                     || image.PixelFormat == PixelFormat.Format4bppIndexed
                                     || image.PixelFormat == PixelFormat.Format8bppIndexed
                                         ? ImageFormat.Tiff
                                         : ImageFormat.Jpeg;
                var pdfImage = iTextSharp.text.Image.GetInstance(image, format);
                pdfImage.Alignment = Element.ALIGN_CENTER;
                pdfImage.SetAbsolutePosition(0, size.Height - pdfImage.Height);
                pdfImage.ScaleToFit(size.Width, size.Height);
                stamp.GetOverContent(page).AddImage(pdfImage);
            }
        }
        ms.Flush();
        return ms.GetBuffer();
}
Jim
  • 14,952
  • 15
  • 80
  • 167
0

You are making the wrong assumption that you can glue the bytes of two PDF documents together.

You have one PDF that looks like this:

%PDF-1.6
%âãÏÓ
1 0 obj <<
... PDF syntax
%%EOF

With another one that looks like this:

%PDF-1.6
%âãÏÓ
1 0 obj <<
... PDF syntax
%%EOF

Resulting in a file that looks like this:

%PDF-1.6
%âãÏÓ
1 0 obj <<
... PDF syntax
%%EOF
%PDF-1.6
%âãÏÓ
1 0 obj <<
... PDF syntax
%%EOF

You really shouldn't expect this to work! Please start by reading chapter 6 of my book and read about called PdfStamper. Then go to this question: How can I insert an image with iTextSharp in an existing PDF?

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • I am trying to add new pages to the PDF, not stamp existing pages on the pdf. – Jim Apr 12 '13 at 05:10
  • I know, but you still need PdfStamper and its insertPage() method (read section 6.3.4 of the free chapter). You certainly don't want to concatenate the bytes of one file to the bytes of another file. – Bruno Lowagie Apr 12 '13 at 07:07