< iOS samples

PDFDrawTest - Swift

This sample illustrates how to use the built-in rasterizer in order to render PDF images on the fly and how to save resulting images in PNG and JPEG format.

//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2017 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

import PDFNet
import Foundation

//---------------------------------------------------------------------------------------
// The following sample illustrates how to convert PDF documents to various raster image
// formats (such as PNG, JPEG, BMP, TIFF, etc), as well as how to convert a PDF page to
// GDI+ Bitmap for further manipulation and/or display in WinForms applications.
//---------------------------------------------------------------------------------------
func runPDFDrawTest() -> Int {
    return autoreleasepool {
        var ret = 0

        do {
            try PTPDFNet.catchException {
                // 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.
                
                
                // Optional: Set ICC color profiles to fine tune color conversion
                // for PDF 'device' color spaces...
                
                // PDFNet::SetResourcesPath("../../../resources");
                // PDFNet::SetColorManagement();
                // PDFNet::SetDefaultDeviceCMYKProfile("D:/Misc/ICC/USWebCoatedSWOP.icc");
                // PDFNet::SetDefaultDeviceRGBProfile("AdobeRGB1998.icc"); // will search in PDFNet resource folder.
                
                // ----------------------------------------------------
                // Optional: Set predefined font mappings to override default font
                // substitution for documents with missing fonts...
                
                // 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::e_Identity, "C:/WINDOWS/Fonts/arialuni.ttf");
                // PDFNet::AddFontSubst(PDFNet::e_Japan1, "C:/Program Files/Adobe/Acrobat 7.0/Resource/CIDFont/KozMinProVI-Regular.otf");
                // PDFNet::AddFontSubst(PDFNet::e_Japan2, "c:/myfonts/KozMinProVI-Regular.otf");
                // PDFNet::AddFontSubst(PDFNet::e_Korea1, "AdobeMyungjoStd-Medium.otf");
                // PDFNet::AddFontSubst(PDFNet::e_CNS1, "AdobeSongStd-Light.otf");
                // PDFNet::AddFontSubst(PDFNet::e_GB1, "AdobeMingStd-Light.otf");
                
                let draw: PTPDFDraw = PTPDFDraw(dpi: 92)   // PDFDraw class is used to rasterize PDF pages.
                
                //--------------------------------------------------------------------------------
                // Example 1) Convert the first page to PNG and TIFF at 92 DPI.
                // A three step tutorial to convert PDF page to an image.
                do {
                    try PTPDFNet.catchException {
                        // A) Open the PDF document.
                        let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "tiger", ofType: "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.
                        draw.export(doc.getPageIterator(1).current(), filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_92dpi.png").path, format: "PNG")
                        
                        print("Example 1: ../../TestFiles/Output/tiger_92dpi.png. Done.")
                        
                        // Export the same page as TIFF
                        draw.export(doc.getPageIterator(1).current(), filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_92dpi.tif").path, format: "TIFF")
                    }
                } catch let e as NSError {
                    print("\(e)")
                    ret = 1
                }

                //--------------------------------------------------------------------------------
                // Example 2) Convert the all pages in a given document to JPEG at 72 DPI.
                print("Example 2:")
                let hint_set: PTObjSet = PTObjSet()   //  A collection of rendering 'hits'.
                do {
                    try PTPDFNet.catchException {
                        let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "newsletter", ofType: "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.
                        let encoder_param: PTObj = hint_set.createDict()
                        encoder_param.putNumber("Quality", value: 80)
                        
                        // Traverse all pages in the document.
                        let itr: PTPageIterator = doc.getPageIterator(1)
                        while itr.hasNext() {
                            let filename: String = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("").path + ("newsletter\(itr.current().getIndex()).jpg")
                            print("\(filename)")
                        
                            //draw.export(withObj: itr.current(), filename: filename, format: "JPEG", encoder_params: encoder_param)
                            itr.next()
                        }

                        print("Done.")
                    }
                } catch let e as NSError {
                    print("\(e)")
                    ret = 1
                }

                // Examples 3-5
                do {
                    try PTPDFNet.catchException {
                        // Common code for remaining samples.
                        let tiger_doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "tiger", ofType: "pdf"))
                        // Initialize the security handler, in case the PDF is encrypted.
                        tiger_doc.initSecurityHandler()
                        let page: PTPage = tiger_doc.getPage(1)
                        
                        //--------------------------------------------------------------------------------
                        // Example 3) Convert the first page to raw bitmap. Also, rotate the
                        // page 90 degrees and save the result as RAW.
                        draw.setDPI(100)  // Set the output resolution is to 100 DPI.
                        draw.setRotate(e_pt90)    // Rotate all pages 90 degrees clockwise.
                        
                        let buf: PTBitmapInfo = draw.getBitmap(page, pix_fmt: e_ptrgb, demult: false)
                        
                        // Save the raw RGB data to disk.
                        do {
                            try buf.getBuffer().write(to: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_100dpi_rot90.raw"), options: [])
                        } catch {
                            
                        }
                        
                        print("Example 3: ../../TestFiles/Output/tiger_100dpi_rot90.raw. Done.")
                        draw.setRotate(e_pt0) // 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.
                        let mono_hint: PTObj = hint_set.createDict()
                        mono_hint.putNumber("BPC", value: 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, height: 1000, preserve_aspect_ratio: true)  // Set the output image to be 1000 wide and 1000 pixels tall
                        draw.export(withObj: page, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_1000x1000.png").path, format: "PNG", encoder_params: mono_hint)
                        print("Example 4: ../../TestFiles/Output/tiger_1000x1000.png. Done.")
                        
                        draw.setImageSize(200, height: 400, preserve_aspect_ratio: true)    // Set the output image to be 200 wide and 300 pixels tall
                        draw.setRotate(e_pt180)   // Rotate all pages 90 degrees clockwise.

                        // 'gray_hint' tells the rasterizer to export the image as grayscale.
                        let gray_hint: PTObj = hint_set.createDict()
                        gray_hint.putName("ColorSpace", name: "Gray")
                        
                        draw.export(withObj: page, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_200x400_rot180.png").path, format: "PNG", encoder_params: gray_hint)
                        print("Example 4: ../../TestFiles/Output/tiger_200x400_rot180.png. Done.")
                        
                        draw.setImageSize(400, height: 200, preserve_aspect_ratio: false)   // The third parameter sets 'preserve-aspect-ratio' to false.
                        draw.setRotate(e_pt0) // Disable image rotation.
                        draw.export(page, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_400x200_stretch.jpg").path, format: "JPEG")
                        print("Example 4: ../../TestFiles/Output/tiger_400x200_stretch.jpg. Done.")
                        
                        //--------------------------------------------------------------------------------
                        // 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).
                        let zoom_rect = PTPDFRect(x1: 216, y1: 522, x2: 330, y2: 600)
                        page.setCropBox(zoom_rect)    // Set the page crop box.

                        // Select the crop region to be used for drawing.
                        draw.setPageBox(e_ptcrop)
                        draw.setDPI(900)  // Set the output image resolution to 900 DPI.
                        draw.export(page, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_zoom_900dpi.png").path, format: "PNG")
                        print("Example 5: ../../TestFiles/Output/tiger_zoom_900dpi.png. Done.")
                        
                        draw.setImageSize(50, height: 50, preserve_aspect_ratio: true)
                        // Set the thumbnail to be 50x50 pixel image.
                        draw.export(page, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("tiger_zoom_50x50.png").path, format: "PNG")
                        print("Example 5: ../../TestFiles/Output/tiger_zoom_50x50.png. Done.")
                    }
                } catch let e as NSError {
                    print("\(e)")
                    ret = 1
                }
                
                let cmyk_hint: PTObj = hint_set.createDict()
                cmyk_hint.putName("ColorSpace", name: "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
                print("Example 7:")
                do {
                    try PTPDFNet.catchException {
                        // A) Open the PDF document.
                        let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "tiger", ofType: "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.
                        let pg: PTPage = doc.getPage(1)
                        draw.export(withObj: pg, filename: URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]).appendingPathComponent("out1.tif").path, format: "TIFF", encoder_params: cmyk_hint)
                        print("Example 7: Result saved in ../../TestFiles/Output/out1.tif")
                    }
                } catch let e as NSError {
                    print("\(e)")
                    ret = 1
                }
                
                //--------------------------------------------------------------------------------
                // 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.
                print("Example 8:")
                do {
                    try PTPDFNet.catchException {
                        // A) Open the PDF document.
                        let doc: PTPDFDoc = PTPDFDoc(filepath: Bundle.main.path(forResource: "tiger", ofType: "pdf"))
                        // Initialize the security handler, in case the PDF is encrypted.
                        doc.initSecurityHandler()
                        
                        // B) Get the page matrix
                        let pg: PTPage = doc.getPage(1)
                        let box: PTBox = e_ptcrop
                        var mtx: PTMatrix2D = pg.getDefaultMatrix(true, box_type: box, angle: e_pt0)
                        // We want to render a quadrant, so use half of width and height
                        let pg_w: Double = pg.getWidth(box) / 2
                        let pg_h: Double = pg.getHeight(box) / 2
                        
                        // C) Scale matrix from PDF space to buffer space
                        let dpi: Double = 96.0
                        let scale: Double = dpi / 72.0  // PDF space is 72 dpi
                        let buf_w = floor(scale * pg_w)
                        let buf_h = floor(scale * pg_h)
                        let bytes_per_pixel: Double = 4    // RGBA buffer
                        _ = (buf_w * buf_h * bytes_per_pixel)
                        mtx.translate(0, v: -pg_h)
                        // translate by '-pg_h' since we want south-west quadrant
                        //mtx = Common::Matrix2D(scale, 0, 0, scale, 0, 0) * mtx;
                        let scale_mtx: PTMatrix2D = PTMatrix2D(a: scale, b: 0, c: 0, d: scale, h: 0, v: 0)
                        mtx = scale_mtx.multiply(mtx)
                        
                        // D) Rasterize page into memory buffer, according to our parameters
                        let rast: PTPDFRasterizer = PTPDFRasterizer(type: e_ptBuiltIn)
                        var _: Data = rast.rasterize(pg, width: Int32(buf_w), height: Int32(buf_h), stride: Int32(buf_w * bytes_per_pixel), num_comps: Int32(bytes_per_pixel), demult: true, device_mtx: mtx, clip: nil, scrl_clip_regions: nil)
                        
                        // buf now contains raw BGRA bitmap.
                        print("Example 8: Successfully rasterized into memory buffer.")
                    }
                } catch let e as NSError {
                    print("\(e)")
                    ret = 1
                }

            }
        } catch let e as NSError {
            print("\(e)")
            ret = 1
        }
        
        return ret
    }
}