Swift: Loss of resolution when redrawing PDF

111 Views Asked by At

I'm trying to use a PDF file (contains a form with table for several 'records') as a template. My idea is to read in the original file as a template, and then use Swifts drawing features to insert the text at the relevant positions before saving as a new pdf file and printing.

My problem is that i'm seeing a small loss of resolution (fonts are slightly wooly, gridlines are no longer crisp) when re-saving the output.

I've tried two approaches, the first with my 'template' as a file in the project, and the second with it as an Asset (Scales: Single Scale, Resizing: Preserve Vector Data).

Here is my code:

func createCompletedForm(records: [MyDataObject]) -> URL? {
    
    let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = URL(fileURLWithPath: "pdfToPrint", relativeTo: directoryURL).appendingPathExtension("pdf")
    guard let templateUrl = Bundle.main.url(forResource: "MyPdfTemplate", withExtension: "pdf") else { return nil }
    guard let document = CGPDFDocument(templateUrl as CFURL) else { return nil }
    guard let page = document.page(at: 1) else { return nil }
    let pageTemplate = page.getBoxRect(.mediaBox)
    
    UIGraphicsBeginPDFContextToFile(fileURL.path, pageTemplate, nil)
    
    guard let pdfContext = UIGraphicsGetCurrentContext() else {
        print("Unable to access PDF Context.")
        return nil
    }
    
    // Mark the beginning of the page.
    pdfContext.beginPDFPage(nil)

    // Save the context state to restore after we are done drawing the image.
    pdfContext.saveGState()

    // Change the PDF context to match the UIKit coordinate system.
    pdfContext.translateBy(x: 0, y: StandardPageDimensions.ISO216_A4.height)
    pdfContext.scaleBy(x: 1, y: -1)

    // Option 1: Draw PDF from a file added to my project
    DrawingHelper.drawPDFfromCGPDF(page: page, drawingArea: pageTemplate)
    
    // Option 2: Draw PDF from Assets
    //let baseTemplate = UIImage(named: "MyPdfTemplate")
    //baseTemplate?.draw(at: CGPoint(x: 0, y: 0))

    // Draw the records over the template - NOT the source of the problem, happens even when commented out
    //addRecordsToTemplate(records: records)

    // Restoring the context back to its original state.
    pdfContext.restoreGState()

    // Mark the end of the current page.
    pdfContext.endPDFPage()
    
    UIGraphicsEndPDFContext()
    
    // Useful to find and open the file produced on the simulator
    print("pdf created at : \(fileURL.path)")
    
    return fileURL
}

    // And the drawing function from my helper class
    static func drawPDFfromCGPDF(page: CGPDFPage, drawingArea: CGRect) {

    let renderer = UIGraphicsImageRenderer(size: drawingArea.size)
    let img = renderer.image { ctx in
        UIColor.white.set()
        ctx.fill(drawingArea)

        ctx.cgContext.translateBy(x: 0.0, y: drawingArea.size.height)
        ctx.cgContext.scaleBy(x: 1.0, y: -1.0)

        ctx.cgContext.drawPDFPage(page)
    }

    img.draw(at: CGPoint(x: 0, y: 0))
}
0

There are 0 best solutions below