Back to Blog

    Developer Blog

    Merge content from multiple pages into one page

    Foxit Quick PDF Library

    Sometimes it’s necessary to customize the content of a document on the fly from templates. There’s various different ways this can be done, but one way is to have a template with different content on each page of a document and then based on certain criteria (i.e. content from page 1, 5, 8 is required to be combined) you can combine this content into one page using The CapturePage and DrawCapturedPage functions. This also allows you to add footers/headers and other template content.

    Here is some sample code written Visual Basic .NET which demonstrates how to determine the content position / height for a page (using pixel analysis) and then draw that content onto the one page in a way that does not overlay the content on other content.

    Public Class Form1
    
        Private Sub btnMergePageContent_Click(sender As Object, e As EventArgs) Handles btnMergePageContent.Click
            Dim QP As New DebenuPDFLibraryAX1113.PDFLibrary
            If QP.UnlockKey("...") = 1 Then
                If QP.LoadFromFile("C:\temp\mutli_page_content.pdf", "") = 1 Then
    
                    ' Remember the original page count
                    Dim pageCount = QP.PageCount()
    
                    ' First create a new page at the end of the document
                    QP.NewPage()
                    QP.SetPageSize("Letter")
    
                    ' Measure the height of all the pages (but not the new blank page)
                    Dim pageHeight(pageCount) As Double
                    For page As Integer = 1 To pageCount
                        QP.SelectPage(page)
                        pageHeight(page - 1) = MeasurePageContentHeight(QP)
                    Next
    
                    ' Capture all the pages (but not the new blank page)
                    Dim captureID(pageCount) As Integer
                    For page As Integer = 1 To pageCount
                        ' Capture page 1 each time because the pages are
                        ' removed from the document as they are captured
                        captureID(page - 1) = QP.CapturePage(1)
                    Next
    
                    ' Set the origin to the top of the page
                    QP.SetOrigin(1)
    
                    ' Draw pages 6, 1, 3, 5 and then 9
                    Dim pagesToDraw() As Integer = {6, 1, 3, 5, 9}
                    Dim currentPosition As Double = 0
    
                    For thisPageIndex As Integer = 1 To UBound(pagesToDraw)
                        ' Look up the page number in the pagesToDraw array
                        Dim thisPageNumber As Integer = pagesToDraw(thisPageIndex - 1)
    
                        ' Draw the captured page (use the full height)
                        QP.DrawCapturedPage(captureID(thisPageNumber - 1), 0, currentPosition, QP.PageWidth(), QP.PageHeight())
    
                        ' Increase the current position
                        currentPosition = currentPosition + pageHeight(thisPageNumber - 1)
                    Next
    
                    QP.SaveToFile("C:\temp\content.pdf")
                End If
            End If
        End Sub
        ' Measures the height of the page content in the current measurement units
        Private Function MeasurePageContentHeight(PDFLibrary As DebenuPDFLibraryAX1113.PDFLibrary) As Double
            Dim Result As Double = 0
    
            Dim bmpBytes() As Byte = PDFLibrary.RenderPageToVariant(96, PDFLibrary.SelectedPage, 0)
    
            Dim bmpStream As New System.IO.MemoryStream(bmpBytes)
            Dim BMP As New Bitmap(bmpStream)
    
            ' Lock the bitmap's bits
            Dim rect As New Rectangle(0, 0, BMP.Width, BMP.Height)
            Dim bmpData As System.Drawing.Imaging.BitmapData = BMP.LockBits(rect, _
            Drawing.Imaging.ImageLockMode.ReadOnly, BMP.PixelFormat)
    
            ' Get the address of the first line
            Dim ptr As IntPtr = bmpData.Scan0
    
            Dim foundPixels = False
            Dim row = BMP.Height
    
            ' Declare an array to hold the bytes of the bitmap
            Dim bytes As Integer = Math.Abs(bmpData.Stride) * BMP.Height
            Dim rgbValues(bytes - 1) As Byte
    
            ' Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
            Dim byteOffset = (BMP.Height - 1) * bmpData.Stride
    
            While (Not foundPixels) And (row > 0)
                row = row - 1
    
                ' Set every third value to 255. A 24bpp image will look red. 
                For counter As Integer = 0 To bmpData.Stride - 1
                    If (rgbValues(byteOffset + counter) <> 255) Then
                        foundPixels = True
                    End If
                Next
    
                byteOffset = byteOffset - bmpData.Stride
            End While
    
            ' Unlock the bits
            BMP.UnlockBits(bmpData)
    
    
            If (foundPixels) Then
                Result = (PDFLibrary.PageHeight() * row) / BMP.Height()
            End If
    
            MeasurePageContentHeight = Result
        End Function
    End Class
    

    This article refers to a deprecated product. If you are looking for support for Foxit PDF SDK, please click here.