Search code examples
iosswiftpdfkit

How PDFPage size is calculated in PDFKit?


All I do in code is to iterate over every image in my set of images:

        print(UIScreen.main.scale) //3.0
        print(UIScreen.main.nativeScale) //3.0
        for card in box.sortedCards {
            if let image = card.image?.scaledWithMaxWidthOrHeightValue(value: 300) {
                print(image.size.width) //300
                print(image.size.height) //300
                if let page = PDFPage(image: image) {
                    document.insert(page, at: document.pageCount)
                }
            }
        }

But once I preview my PDFDocument using UIActivityViewController and then share it to my macbook, I get the following result:

enter image description here

How it is calculated?

Every image shared to my mac via UIActivityViewController has following info:

enter image description here

What do I need?

I need to calculate image size, to preview PDFDocument with every page exactly 10 centimeters on 10 centimeters, no matter what ios device will be used for it.


Solution

  • How it is calculated

    The physical size of the image in pixels equals to the logical size of the image multiplied by the scale factor of the image.

    Image Size (pixels) = UIImage.size * UIImage.scale
    

    The DPI of the image is 72 pixels per inch if the scale factor is 1.

    Image DPI (pixels/inch) = UIImage.scale * 72.0
    

    To get the size of page:

    Page Size (inches) = Image Size / Image DPI
    

    How to get page of exact 10 x 10 cm size

    I'm not sure how your scaledWithMaxWidthOrHeightValue is implemented. To illustrate the calculation, I'm assuming that you already have an instance of UIImage with size 300x300.

    print(UIScreen.main.scale) //3.0
    print(UIScreen.main.nativeScale) //3.0
    for card in box.sortedCards {
        if let image = card.image?.scaledWithMaxWidthOrHeightValue(value: 300) {
            print(image.size.width) //300
            print(image.size.height) //300
            let defaultDPI = 72.0
            let centimetersPerInch = 2.54
            let expectedPageSize = 10.0 // centimeters
            var scale = 300.0 / defaultDPI * centimetersPerInch / expectedPageSize * image.scale.native
            scale += 0.001 // work around accuracy to get exact 10 centimeters
            if let cgImage = image.cgImage {
                let scaledImage: UIImage = UIImage(cgImage: cgImage, scale: CGFloat(scale), orientation: image.imageOrientation)
                if let page = PDFPage(image: scaledImage) {
                    document.insert(page, at: document.pageCount)
                }
            }
        }
    }