Skip to content

Instantly share code, notes, and snippets.

@manmal
Last active February 8, 2022 20:29
Show Gist options
  • Save manmal/f9c7692e0e41570c05633155d95e8910 to your computer and use it in GitHub Desktop.
Save manmal/f9c7692e0e41570c05633155d95e8910 to your computer and use it in GitHub Desktop.
PDF to UIImage (with capability to resize)
import Foundation
import UIKit
/// Renders the first page of the given PDF file to a `UIImage`. If
/// `maxLength` is given, then the resulting image is scaled to a
/// matching size.
///
/// Example: If `maxLength` is set to `100.0`, this might result in
/// the following dimensions (since aspect ratio is preserved):
///
/// +------50-----+
/// | |
/// | |
/// | |
/// | |
/// 100 |
/// | |
/// | |
/// | |
/// | |
/// +-------------+
///
/// +-----------100-----------+
/// | |
/// 30 |
/// | |
/// +-------------------------+
///
/// Inspired by Paul Hudson's post on PDF rendering:
/// https://www.hackingwithswift.com/example-code/core-graphics/how-to-render-a-pdf-to-an-image
///
/// - Parameters:
/// - url: The file URL to the PDF document
/// - maxLength: The max length of the resulting UIImage, in points at main screen scale
/// - Returns: An image if the PDF can be rendered
func drawPDF(_ url: URL, maxLength: CGFloat?) -> UIImage? {
guard let document = CGPDFDocument(url as CFURL) else { return nil }
guard let page = document.page(at: 1) else { return nil }
let pageRect = page.getBoxRect(.mediaBox)
let (width, height): (CGFloat, CGFloat) = {
guard let maxLength = maxLength else {
return (pageRect.width, pageRect.height)
}
let aspectRatio = pageRect.width / pageRect.height
if aspectRatio >= 1 {
return (maxLength, maxLength / aspectRatio)
} else {
return (maxLength / (1 / aspectRatio), maxLength)
}
}()
let scale = width / pageRect.width
let renderer = UIGraphicsImageRenderer(size: .init(width: width, height: height))
return renderer.image { ctx in
ctx.cgContext.translateBy(x: 0.0, y: height)
ctx.cgContext.scaleBy(x: scale, y: -scale)
ctx.cgContext.drawPDFPage(page)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment