Skip to main content

Merge multiple GIF, PNG, JPG, TIFF and PDF files into a single PDF file with C# using the iTextSharp library.

//
// Merge multiple GIF, PNG, JPG, TIFF and PDF files into a single PDF file with
// ASP.NET C# using the iTextSharp library
//
// Dependencies:
// - iTextSharp (https://www.nuget.org/packages/iTextSharp/)
//
// https://www.ryadel.com/en/merge-multiple-gif-png-jpg-pdf-image-files-single-pdf-file-asp-net-c-sharp-core-itextsharp/
//

public static byte[] ConvertIntoSinglePDF(List<string> filePaths)
{
    Document doc = new Document();
    doc.SetPageSize(PageSize.A4);

    var ms = new MemoryStream();
    {
        PdfCopy pdf = new PdfCopy(doc, ms);
        doc.Open();

        foreach (string path in filePaths)
        {
            byte[] data = File.ReadAllBytes(path);
            doc.NewPage();
            Document imageDocument = null;
            PdfWriter imageDocumentWriter = null;
            switch (Path.GetExtension(path).ToLower().Trim('.'))
            {
                case "bmp":
                case "gif":
                case "jpg":
                case "png":
                    imageDocument = new Document();
                    using (var imageMS = new MemoryStream())
                    {
                        imageDocumentWriter = PdfWriter.GetInstance(imageDocument, imageMS);
                        imageDocument.Open();
                        if (imageDocument.NewPage())
                        {
                            var image = iTextSharp.text.Image.GetInstance(data);
                            image.Alignment = Element.ALIGN_CENTER;
                            image.ScaleToFit(doc.PageSize.Width - 10, doc.PageSize.Height - 10);
                            if (!imageDocument.Add(image))
                            {
                                throw new Exception("Unable to add image to page!");
                            }
                            imageDocument.Close();
                            imageDocumentWriter.Close();
                            PdfReader imageDocumentReader = new PdfReader(imageMS.ToArray());
                            var page = pdf.GetImportedPage(imageDocumentReader, 1);
                            pdf.AddPage(page);
                            imageDocumentReader.Close();
                        }
                    }
                    break;
                case "tif":
                case "tiff":
                    // STEP 1: trasform the TIFF pages/frames into a more usable Bitmap list
                    List<System.Drawing.Bitmap> bmpLst = new List<System.Drawing.Bitmap>();
                    using (var msTemp = new MemoryStream(data))
                    {
                        TiffBitmapDecoder decoder = new TiffBitmapDecoder(msTemp, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                        int totFrames = decoder.Frames.Count;

                        for (int i = 0; i < totFrames; ++i)
                        {
                            // Create bitmap to hold the single frame
                            System.Drawing.Bitmap bmpSingleFrame = BitmapFromSource(decoder.Frames[i]);
                            // add the frame (as a bitmap) to the bitmap list
                            bmpLst.Add(bmpSingleFrame);
                        }
                    }

                    // STEP 2: insert the Bitmap list elements into the PDF
                    ImageConverter converter = new ImageConverter();
                    foreach (Bitmap bmp in bmpLst)
                    {
                        imageDocument = new Document();
                        using (var imageMS = new MemoryStream())
                        {
                            imageDocumentWriter = PdfWriter.GetInstance(imageDocument, imageMS);
                            imageDocument.Open();
                            if (imageDocument.NewPage())
                            {
                                using (Bitmap tmp = new Bitmap(bmp))    // this is required!
                                {
                                    var image = iTextSharp.text.Image.GetInstance((byte[])converter.ConvertTo(tmp, typeof(byte[])));
                                    image.Alignment = Element.ALIGN_CENTER;
                                    image.ScaleToFit(doc.PageSize.Width - 10, doc.PageSize.Height - 10);
                                    if (!imageDocument.Add(image))
                                    {
                                        throw new Exception("Unable to add image to page!");
                                    }
                                    imageDocument.Close();
                                    imageDocumentWriter.Close();
                                    PdfReader imageDocumentReader = new PdfReader(imageMS.ToArray());
                                    var page = pdf.GetImportedPage(imageDocumentReader, 1);
                                    pdf.AddPage(page);
                                    imageDocumentReader.Close();
                                }
                            }
                        }
                    }
                    break;
                case "pdf":
                    var reader = new PdfReader(data);
                    for (int i = 0; i < reader.NumberOfPages; i++)
                    {
                        pdf.AddPage(pdf.GetImportedPage(reader, i + 1));
                    }
                    pdf.FreeReader(reader);
                    reader.Close();
                    break;
                default:
                    // not supported image format:
                    // skip it (or throw an exception if you prefer)
                    break;
            }
        }

        if (doc.IsOpen()) doc.Close();
        return ms.ToArray();
    }
}

public static BitmapSource ConvertBitmap(Bitmap source)
{
    return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    source.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
}

public static Bitmap BitmapFromSource(BitmapSource bitmapsource)
{
    Bitmap bitmap;
    using (var outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapsource));
        enc.Save(outStream);
        bitmap = new Bitmap(outStream);
    }
    return bitmap;
}