Reputation: 933
I'm trying to get the image(high quality) of each pdf page. I'm using below code running through a for loop until page count and it works.
guard let document = CGPDFDocument(pdfurl as CFURL) else { return }
guard let page = document.page(at: i) else { return }
let dpi: CGFloat = 300.0/72.0
let pagerect = page.getBoxRect(.mediaBox)
print(pagebounds)
print(pagerect)
let render = UIGraphicsImageRenderer(size: CGSize(width: pagerect.size.width * dpi, height: pagerect.size.height * dpi))
let imagedata = render.jpegData(withCompressionQuality: 0.5, actions: { cnv in
UIColor.white.set()
cnv.fill(pagerect)
cnv.cgContext.translateBy(x: 0.0, y: pagerect.size.height * dpi)
cnv.cgContext.scaleBy(x: dpi, y: -dpi)
cnv.cgContext.drawPDFPage(page)
})
let image = UIImage(data: imagedata)
I'm getting following issues with this ...
image
is nil
.memory is very high
.1.4 GB
and suddenly it crashes the app with the warning : Terminate due to memory waring
. then I tried to run above code inside autoreleasepool
. it did work but when the memory usage is more high (when it near to RAM size), again app crashes with above warning.How can I avoid this memory warning and get the quality image form pdf page. hope any help. have a nice day.
Upvotes: 3
Views: 535
Reputation: 11
If you are facing this issue then try this:
autoreleasepool {
guard let page = document.page(at: i) else { return }
// Fetch the page rect for the page we want to render.
let pageRect = page.getBoxRect(.mediaBox)
var dpi: CGFloat = 1.0
if pageRect.size.width > pageRect.size.height {
dpi = 3508.0 / pageRect.size.width
} else {
dpi = 3508.0 / pageRect.size.height
}
//dpi = 300
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let renderer = UIGraphicsImageRenderer(size: CGSize(width: pageRect.size.width * dpi, height: pageRect.size.height * dpi), format: format)
let imagedata = renderer.jpegData(withCompressionQuality: 1.0, actions: { cnv in
UIColor.white.set()
cnv.fill(pageRect)
cnv.cgContext.translateBy(x: 0.0, y: pageRect.size.height * dpi)
cnv.cgContext.scaleBy(x: dpi, y: -dpi)
cnv.cgContext.drawPDFPage(page)
})
let image = UIImage(data: imagedata)
}
autoreleasepool - for permanent memory clearing
scale - so that images for different devices are not created, which increases their resolution by 2 or 3 times
changed the way to increase dpi as it can be initially more or less than 72
Upvotes: 1
Reputation: 873
1) sometimes the image is nil.
UIImage
VS directly creating an uiimage (using func image(actions: (UIGraphicsImageRendererContext) -> Void) -> UIImage
)? UIImage(data:)
, use CGImage's init?(jpegDataProviderSource source: CGDataProvider,
decode: UnsafePointer<CGFloat>?,
shouldInterpolate: Bool,
intent: CGColorRenderingIntent)
then use UIImage(cgImage:)
to get your UIImage
instance2) When this runs, the usage of memory is very high
Upvotes: 0