1

I have the following classes:

import Foundation
import PDFKit
import SwiftUI

struct PDFPreviewView  : View {
    @State private var showShareSheet : Bool = false
    
    var pdfData: Data? {
        LabelPDFCreator().pdfData()
    }
    
    var body: some View {
        VStack {
            PdfViewUI(data: pdfData)
        }
        .navigationTitle(Text("Your Labels"))
        .navigationBarTitleDisplayMode(.inline)
        .sheet(isPresented: $showShareSheet, content: {
            if let data = pdfData {
                ShareView(activityItems: [data])
            }
        })
        .toolbar {
            Button {
                self.showShareSheet.toggle()
            } label: {
                Label("Options", systemImage: "square.and.arrow.up")
            }
        }
    }
}

struct PdfViewUI : UIViewRepresentable {

    private var data: Data?
    
    private let autoScales : Bool
    
    init(data : Data?, autoScales : Bool = true ) {
        self.data = data
        self.autoScales = autoScales
    }

    func makeUIView(context: Context) -> PDFView {
        let pdfView = PDFView()

        pdfView.autoScales =  self.autoScales
       
        if let data = self.data {
            pdfView.document = PDFDocument(data: data)
        }
        
        return pdfView
    }

    func updateUIView(_ uiView: PDFView, context: Context) {
        // Empty
    }
}

class LabelPDFCreator : NSObject {
    static let DPI = 72.0
    
    private var pageRect : CGRect
    private var renderer : UIGraphicsPDFRenderer?
    
    let context = CIContext()
    let filter = CIFilter.qrCodeGenerator()

    override init() {
        let format = UIGraphicsPDFRendererFormat()
        
        let pageRect = CGRect(x: 0, y: 0, width: (8.5 * LabelPDFCreator.DPI), height: (11.0 * LabelPDFCreator.DPI))
        self.pageRect = pageRect
        self.renderer = UIGraphicsPDFRenderer(bounds: self.pageRect,
                                             format: format)
        super.init()
    }
    
    func pdfData() -> Data? {
        if let renderer = self.renderer {
            let data = renderer.pdfData { ctx in
                ctx.beginPage()

                let image = generateQRCode(from: UUID().uuidString)
                let imageWidthHeight = 1.0 * LabelPDFCreator.DPI
                                    
                image.draw(in: CGRect(x: LabelPDFCreator.DPI, y : LabelPDFCreator.DPI, width: imageWidthHeight, height: imageWidthHeight))
            }
            return data
        }
        return nil
    }
    
    func generateQRCode(from id: String) -> UIImage {
        filter.message = Data(id.utf8)
        
        if let outputImage = filter.outputImage {
            if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                return UIImage(cgImage: cgImage)
            }
        }
        
        return UIImage(systemName: "xmark.circle") ?? UIImage()
    }
}

I have simplified the code down to the core functionality that I am experiencing issues with.

Within LabelPDFCreator, you can see that I am generate a QR code UIImage from a UUID string, and then drawing that image onto a page of a PDF using PDFKit.

The draw is successful, however the QR code winds up being very blurry. Am I able to adjust this code in a way that will result in a sharper display of the QR code in the PDF?

I have tried to scale up both the bounds of the UIGraphicsPDFRenderer, and the width and height of the image being drawn into the PDF, but this effort was unsuccessful.

0 Answers0