-1

Some context first:

I simply draw a UIImage to a PDFPage by subclassing PDFPage and overriding draw(with box,to context):

override func draw(with box: PDFDisplayBox, to context: CGContext) {
    /* Draw image on PDF */
    UIGraphicsPushContext(context)
    // Change the PDF context to match the UIKit coordinate system.
    context.translateBy(x: 0, y: pageBounds.height)
    context.scaleBy(x: 1, y: -1)
    context.interpolationQuality = .high

    // The important line is here: drawing the image
    self.myImage.draw(in: CGRect(x: leftMargin, y: topMargin, width: fittedImageSize.width, height: fittedImageSize.height))
}

where self.myImage contains a UIImage. So far so good.

The problem -> if I persist the image to save memory If I init my CustomPDFPage with the original UIImage from memory --> I get a PDF file with a reasonable size, everything works well

However: if I persist the image using pngData(), then reload it using UIImage(contentsOfFile: url.path) for drawing, my PDF file is suddenly MUCH more heavier in size.

Writing the image to TMP:

let urlToWrite = tmpDir.appendingPathComponent(fileName)
do {
    if let tmpData = image.png() {
        DLog("TMPDATA SIZE = \(tmpData.count). Image dimensions = \(image.size) with scale = \(image.scale)")
    }
    try image.pngData()?.write(to: urlToWrite) 
    self.tmpImgURL = urlToWrite
} catch {
    DLog("ERROR: could not write image to \(urlToWrite). Error is \(error)")
}

Reloading the image into memory:

var image = UIImage(contentsOfFile: self.tmpImgURL.path)

--> using that image to draw the PDF increases the PDF size dramatically.

Inspecting the UIImage size, the scale, and the bytes count of the image before writing to file and after reading to file give the exact same values.

vomi
  • 993
  • 8
  • 18
  • `var image UIImage(contentsOfFile: self.self.tmpImgURL.path)`, there should be a "=" and what is `self.self.tmpImgURL.path`. What do you do with the `image` to "draw" it into a pdf document? – workingdog support Ukraine May 02 '22 at 10:16
  • The image has been resized or been applied some filters (grayscale). – vomi May 02 '22 at 10:19
  • I must add that the problem is the same if I do image = UIImage(data: image.pngData()!) – vomi May 02 '22 at 10:20

1 Answers1

0

So the reason behind this mess is because the user has the possibility to choose to reduce the quality of the image. In that case, the source UIImage was an image recreated from jpegData (that was used to apply compression).

In short, calling UIImage.pngData() after UIImage.jpegData(...) is not a good idea. Just write directly the jpegData when the image might have been compressed.

vomi
  • 993
  • 8
  • 18