'---------------------------------------------------------------------------------------
' Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
' Consult legal.txt regarding legal and license information.     
'---------------------------------------------------------------------------------------
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices

Imports pdftron
Imports pdftron.Common
Imports pdftron.SDF
Imports pdftron.PDF

' <summary>
'---------------------------------------------------------------------------------------
' The following sample illustrates how to convert PDF documents to various raster image 
' formats (such as PNG, JPEG, BMP, TIFF), as well as how to convert a PDF page to GDI+ Bitmap 
' for further manipulation and/or display in WinForms applications.
'---------------------------------------------------------------------------------------
' </summary>
Module PDFDrawTestVB
    Dim pdfNetLoader As PDFNetLoader
    Sub New()
        pdfNetLoader = pdftron.PDFNetLoader.Instance()
    End Sub

    ' The main entry point for the application.
    Sub Main()

        ' The first step in every application using PDFNet is to initialize the 
        ' library and set the path to common PDF resources. The library is usually 
        ' initialized only once, but calling Initialize() multiple times is also fine.
        PDFNet.Initialize(PDFTronLicense.Key)

        ' Try
        ' Optional: Set ICC color profiles to fine tune color conversion 
        ' for PDF 'device' color spaces. You can use your own ICC profiles. 
        ' Standard Adobe color profiles can be download from Adobes site: 
        ' http://www.adobe.com/support/downloads/iccprofiles/iccprofiles_win.html
        '
        ' Simply drop all *.icc files in PDFNet resource folder or you specify 
        ' the full pathname.
        '---
        ' PDFNet.SetResourcesPath("../../../../resources")
        ' PDFNet.SetColorManagement()
        ' PDFNet.SetDefaultDeviceCMYKProfile("USWebCoatedSWOP.icc") ' will search in PDFNet resource folder.
        ' PDFNet.SetDefaultDeviceRGBProfile("AdobeRGB1998.icc") 

        ' Optional: Set predefined font mappings to override default font 
        ' substitution for documents with missing fonts. For example:
        '---
        ' PDFNet.AddFontSubst("StoneSans-Semibold", "C:/WINDOWS/Fonts/comic.ttf")
        ' PDFNet.AddFontSubst("StoneSans", "comic.ttf")  ' search for 'comic.ttf' in PDFNet resource folder.
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_Identity, "C:/WINDOWS/Fonts/arialuni.ttf")
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_Japan1, "C:/Program Files/Adobe/Acrobat 7.0/Resource/CIDFont/KozMinProVI-Regular.otf")
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_Japan2, "c:/myfonts/KozMinProVI-Regular.otf")
        '
        ' If fonts are in PDFNet resource folder, it is not necessary to specify 
        ' the full path name. For example,
        '---
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_Korea1, "AdobeMyungjoStd-Medium.otf")
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_CNS1, "AdobeSongStd-Light.otf")
        ' PDFNet.AddFontSubst(PDFNet.CharacterOrdering.e_GB1, "AdobeMingStd-Light.otf")
        ' Catch e As PDFNetException
        '   Console.WriteLine(e.Message)
        ' End Try

        ' Relative path to the folder containing test files.
        Dim input_path As String = "../../../../TestFiles/"
        Dim output_path As String = "../../../../TestFiles/Output/"

        Using draw As PDFDraw = New PDFDraw     ' PDFDraw class is used to rasterize PDF pages.

            '--------------------------------------------------------------------------------
            ' Example 1) Convert the first PDF page to PNG at 92 DPI. 
            ' A three step tutorial to convert PDF page to an image.
            Try
                ' A) Open the PDF document.
                Using doc As PDFDoc = New PDFDoc(input_path + "tiger.pdf")
                    ' Initialize the security handler, in case the PDF is encrypted.
                    doc.InitSecurityHandler()

                    ' B) The output resolution is set to 92 DPI.
                    draw.SetDPI(92)

                    ' C) Rasterize the first page in the document and save the result as PNG.
                    Dim pg As Page = doc.GetPage(1)
                    draw.Export(pg, output_path + "tiger_92dpi.png")

                    Console.WriteLine("Example 1: tiger_92dpi.png")

                    ' Export the same page as TIFF
                    draw.Export(pg, output_path + "tiger_92dpi.tif", "TIFF")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try


            '--------------------------------------------------------------------------------
            ' Example 2) Convert the all pages in a given document to JPEG at 72 DPI.
            Console.WriteLine("Example 2:")
            Dim hint_set As ObjSet = New ObjSet    ' A collection of rendering 'hits'.
            Try
                Using doc As PDFDoc = New PDFDoc(input_path + "newsletter.pdf")
                    ' Initialize the security handler, in case the PDF is encrypted.
                    doc.InitSecurityHandler()

                    draw.SetDPI(72)              ' Set the output resolution is to 72 DPI.

                    ' Use optional encoder parameter to specify JPEG quality.
                    Dim encoder_param As SDF.Obj = hint_set.CreateDict()
                    encoder_param.PutNumber("Quality", 80)

                    ' Traverse all pages in the document.
                    Dim itr As PageIterator = doc.GetPageIterator()

                    While itr.HasNext()
                        Dim outname As String = String.Format("newsletter{0:d}.jpg", itr.GetPageNumber())
                        Console.WriteLine(outname)
                        draw.Export(itr.Current(), output_path + outname, "JPEG", encoder_param)
                        itr.Next()
                    End While

                    Console.WriteLine("Done.")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try


            ' Examples(3 - 6)
            Try
                ' Common code for remaining samples.
                Using tiger_doc As PDFDoc = New PDFDoc(input_path + "tiger.pdf")
                    ' Initialize the security handler, in case the PDF is encrypted.
                    tiger_doc.InitSecurityHandler()
                    Dim page As Page = tiger_doc.GetPage(1)

                    '--------------------------------------------------------------------------------
                    ' Example 3) Convert the first page to GDI+ Bitmap. Also, rotate the 
                    ' page 90 degrees and save the result as TIFF.
                    draw.SetDPI(100)              ' Set the output resolution is to 100 DPI.
                    draw.SetRotate(page.Rotate.e_90)              ' Rotate all pages 90 degrees clockwise.

                    Dim bmp As System.Drawing.Bitmap = draw.GetBitmap(page)
                    ' Save the raw RGB data to disk.
                    System.IO.File.WriteAllBytes(output_path + "tiger_100dpi_rot90.raw", BitmapToByteArray(bmp))

                    Console.WriteLine("Example 3: tiger_100dpi_rot90.raw")
                    draw.SetRotate(page.Rotate.e_0)              ' Disable image rotation for remaining samples.

                    '--------------------------------------------------------------------------------
                    ' Example 4) Convert PDF page to a fixed image size. Also illustrates some 
                    ' other features in PDFDraw class such as rotation, image stretching, exporting 
                    ' to grayscale, or monochrome.

                    ' Initialize render 'gray_hint' parameter, that is used to control the 
                    ' rendering process. In this case we tell the rasterizer to export the image as 
                    ' 1 Bit Per Component (BPC) image.
                    Dim mono_hint As Obj = hint_set.CreateDict()
                    mono_hint.PutNumber("BPC", 1)

                    ' SetImageSize can be used instead of SetDPI() to adjust page  scaling 
                    ' dynamically so that given image fits into a buffer of given dimensions.
                    draw.SetImageSize(1000, 1000)            ' Set the output image to be 1000 wide and 1000 pixels tall
                    draw.Export(page, output_path + "tiger_1000x1000.png", "PNG", mono_hint)
                    Console.WriteLine("Example 4: tiger_1000x1000.png")

                    draw.SetImageSize(200, 400)            ' Set the output image to be 200 wide and 300 pixels tall
                    draw.SetRotate(page.Rotate.e_180)            ' Rotate all pages 90 degrees clockwise.

                    ' 'gray_hint' tells the rasterizer to export the image as grayscale.
                    Dim gray_hint As Obj = hint_set.CreateDict()
                    gray_hint.PutName("ColorSpace", "Gray")

                    draw.Export(page, output_path + "tiger_200x400_rot180.png", "PNG", gray_hint)
                    Console.WriteLine("Example 4: tiger_200x400_rot180.png")

                    draw.SetImageSize(400, 200, False)              ' The third parameter sets 'preserve-aspect-ratio' to false.
                    draw.SetRotate(page.Rotate.e_0)             ' Disable image rotation.
                    draw.Export(page, output_path + "tiger_400x200_stretch.jpg", "JPEG")
                    Console.WriteLine("Example 4: tiger_400x200_stretch.jpg")


                    '--------------------------------------------------------------------------------
                    ' Example 5) Zoom into a specific region of the page and rasterize the 
                    ' area at 200 DPI and as a thumbnail (i.e. a 50x50 pixel image).
                    page.SetCropBox(New Rect(216, 522, 330, 600))             ' Set the page crop box.

                    ' Select the crop region to be used for drawing.
                    draw.SetPageBox(page.Box.e_crop)
                    draw.SetDPI(900)              ' Set the output image resolution to 900 DPI.
                    draw.Export(page, output_path + "tiger_zoom_900dpi.png", "PNG")
                    Console.WriteLine("Example 5: tiger_zoom_900dpi.png")

                    draw.SetImageSize(50, 50)             ' Set the thumbnail to be 50x50 pixel image.
                    draw.Export(page, output_path + "tiger_zoom_50x50.png", "PNG")
                    Console.WriteLine("Example 6: tiger_zoom_50x50.png")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try

            Dim cmyk_hint As Obj = hint_set.CreateDict()
            cmyk_hint.PutName("ColorSpace", "CMYK")

            '--------------------------------------------------------------------------------
            ' Example 7) Convert the first PDF page to CMYK TIFF at 92 DPI. 
            ' A three step tutorial to convert PDF page to an image.
            Try
                ' A) Open the PDF document.
                Using doc As New PDFDoc(input_path & "tiger.pdf")
                    ' Initialize the security handler, in case the PDF is encrypted.
                    doc.InitSecurityHandler()

                    ' B) The output resolution is set to 92 DPI.
                    draw.SetDPI(92)

                    ' C) Rasterize the first page in the document and save the result as TIFF.
                    Dim pg As Page = doc.GetPage(1)
                    draw.Export(pg, output_path & "out1.tif", "TIFF", cmyk_hint)
                    Console.WriteLine("Example 7: out1.tif")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try

            '--------------------------------------------------------------------------------
            ' Example 8) PDFRasterizer can be used for more complex rendering tasks, such as 
            ' strip by strip or tiled document rendering. In particular, it is useful for 
            ' cases where you cannot simply modify the page crop box (interactive viewing,
            ' parallel rendering).  This example shows how you can rasterize the south-west
            ' quadrant of a page.
            Using rast As PDFRasterizer = New PDFRasterizer
                Try
                    ' A) Open the PDF document.
                    Using doc As PDFDoc = New PDFDoc(input_path & "tiger.pdf")
                        ' Initialize the security handler, in case the PDF is encrypted.
                        doc.InitSecurityHandler()

                        ' B) Get the page matrix 
                        Dim pg As Page = doc.GetPage(1)
                        Dim box As Page.Box = Page.Box.e_crop
                        Dim mtx As Matrix2D = pg.GetDefaultMatrix(True, box)

                        ' We want to render a quadrant, so use half of width and height
                        Dim pg_w As Double = pg.GetPageWidth(box) / 2
                        Dim pg_h As Double = pg.GetPageHeight(box) / 2

                        ' C) Scale matrix from PDF space to buffer space
                        Dim dpi As Double = 96.0
                        Dim scale As Double = dpi / 72.0 ' PDF space is 72 dpi
                        Dim buf_w As Double = Math.Floor(scale * pg_w)
                        Dim buf_h As Double = Math.Floor(scale * pg_h)
                        Dim bytes_per_pixel As Integer = 4 ' RGBA buffer
                        Dim buf_size As Double = buf_w * buf_h * bytes_per_pixel
                        mtx.Translate(0, -pg_h) ' translate by '-pg_h' since we want south-west quadrant
                        mtx = (New Matrix2D(scale, 0, 0, scale, 0, 0)) * mtx

                        ' D) Rasterize page into memory buffer, according to our parameters
                        Dim buf As Byte() = rast.Rasterize(pg, CType(buf_w, Integer), CType(buf_h, Integer), CType(buf_w * bytes_per_pixel, Integer), bytes_per_pixel, True, mtx)


                    End Using
                    Console.WriteLine("Example 8: Successfully rasterized into memory buffer.")
                Catch e As PDFNetException
                    Console.WriteLine(e.Message)
                End Try
            End Using

            '--------------------------------------------------------------------------------
            ' Example 9) Export raster content to PNG using different image smoothing settings. 
            Try
                ' A) Open the PDF document.
                Using doc As New PDFDoc(input_path & "lorem_ipsum.pdf")
                    ' Initialize the security handler, in case the PDF is encrypted.
                    doc.InitSecurityHandler()

                    ' B) The output resolution is set to 92 DPI.
                    draw.SetDPI(92)

                    ' C) Rasterize the first page in the document and save the result as TIFF.
                    Dim pg As Page = doc.GetPage(1)
                    ' Rasterize it without image smoothing
                    Dim filename As String = "raster_text_no_smoothing.png"
                    draw.SetImageSmoothing(False, False)
                    draw.Export(pg, output_path + filename)
                    Console.WriteLine("Example 9 a): " + filename + ". Done.")

                    ' Rasterize it with image smoothing
                    filename = "raster_text_smoothed.png"
                    draw.SetImageSmoothing(True, False)
                    draw.Export(pg, output_path + filename)
                    Console.WriteLine("Example 9 b): " + filename + ". Done.")

                    'rasterize it with high quality area resampling
                    filename = "raster_text_high_quality.png"
                    draw.SetImageSmoothing(True, True)
                    draw.Export(pg, output_path + filename)
                    Console.WriteLine("Example 9 c): " + filename + ". Done.")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try

            '--------------------------------------------------------------------------------
            ' Example 10) Export separations directly, without conversion to an output colorspace 
            Try
                Using separation_doc As New PDFDoc(input_path & "op_blend_test.pdf")

                    separation_doc.InitSecurityHandler()

                    Dim separation_hint As Obj = hint_set.CreateDict()
                    separation_hint.PutName("ColorSpace", "Separation")
                    draw.SetDPI(96)
                    draw.SetImageSmoothing(True, True)
                    'set overprint preview to always on
                    draw.SetOverprint(PDFRasterizer.OverprintPreviewMode.e_op_on)

                    Dim filename As String = "merged_separations.png"
                    draw.Export(separation_doc.GetPage(1), output_path & filename, "PNG")
                    Console.WriteLine("Example 10 a): " & filename + ". Done.")

                    filename = "separation"
                    draw.Export(separation_doc.GetPage(1), output_path & filename, "PNG", separation_hint)
                    Console.WriteLine("Example 10 b): " & filename & "_[ink].png. Done.")

                    filename = "separation_NChannel.tif"
                    draw.Export(separation_doc.GetPage(1), output_path & filename, "TIFF", separation_hint)
                    Console.WriteLine("Example 10 c): " & filename & ". Done.")
                End Using

            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try
        End Using
        PDFNet.Terminate()
    End Sub


    Public Function BitmapToByteArray(ByVal bitmap As Bitmap) As Byte()
        Dim bmpdata As BitmapData = Nothing
        Try
            bmpdata = bitmap.LockBits(New Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat)
            Dim numbytes As Integer = (bmpdata.Stride * bitmap.Height)
            Dim bytedata() As Byte = New Byte((numbytes) - 1) {}
            Dim ptr As IntPtr = bmpdata.Scan0
            Marshal.Copy(ptr, bytedata, 0, numbytes)
            Return bytedata
        Finally
            If (Not (bmpdata) Is Nothing) Then
                bitmap.UnlockBits(bmpdata)
            End If

        End Try

    End Function

End Module
