Skip to content

Instantly share code, notes, and snippets.

@aplekhanov
Forked from mindbrix/UIImage+PDF.swift
Last active December 19, 2017 09:44
Show Gist options
  • Save aplekhanov/1da0f6a2799b45b680d0f491f443c4f0 to your computer and use it in GitHub Desktop.
Save aplekhanov/1da0f6a2799b45b680d0f491f443c4f0 to your computer and use it in GitHub Desktop.
//
// UIImage+PDF.swift. Copyright © 2016 Nigel Timothy Barber (@mindbrix). All rights reserved.
//
import UIKit
extension UIImage {
static func PDFImageWith(_ url: URL, pageNumber: Int, width: CGFloat) -> UIImage? {
return PDFImageWith(url, pageNumber: pageNumber, constraints: CGSize(width: width, height: 0))
}
static func PDFImageWith(_ url: URL, pageNumber: Int, height: CGFloat) -> UIImage? {
return PDFImageWith(url, pageNumber: pageNumber, constraints: CGSize(width: 0, height: height))
}
static func PDFImageWith(_ url: URL, pageNumber: Int) -> UIImage? {
return PDFImageWith(url, pageNumber: pageNumber, constraints: CGSize(width: 0, height: 0))
}
static func PDFImageWith(_ url: URL, pageNumber: Int, constraints: CGSize) -> UIImage? {
if let pdf = CGPDFDocument(url as CFURL) {
if let page = pdf.page(at: pageNumber) {
let size = page.getBoxRect(.mediaBox).size.forConstraints(constraints)
let cacheURL = url.PDFCacheURL(pageNumber, size: size)
if let url = cacheURL {
if FileManager.default.fileExists(atPath: url.path) {
if let image = UIImage(contentsOfFile: url.path) {
return UIImage(cgImage: image.cgImage!, scale: UIScreen.main.scale, orientation: .up)
}
}
}
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
if let ctx = UIGraphicsGetCurrentContext() {
ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
let rect = page.getBoxRect(.mediaBox)
ctx.translateBy(x: -rect.origin.x, y: -rect.origin.y)
ctx.scaleBy(x: size.width / rect.size.width, y: size.height / rect.size.height)
// CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(page, .MediaBox, CGRectMake(0, 0, size.width, size.height), 0, true))
ctx.drawPDFPage(page)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let image = image {
if let url = cacheURL {
if let imageData = UIImagePNGRepresentation(image) {
try? imageData.write(to: url, options: [])
}
}
return UIImage(cgImage: image.cgImage!, scale: UIScreen.main.scale, orientation: .up)
}
}
}
}
return nil
}
static func PDFImageSizeWith(_ url: URL, pageNumber: Int, width: CGFloat) -> CGSize {
if let pdf = CGPDFDocument(url as CFURL) {
if let page = pdf.page(at: pageNumber) {
return page.getBoxRect(.mediaBox).size.forConstraints(CGSize(width: width, height: 0))
}
}
return CGSize.zero
}
}
extension CGSize {
func forConstraints(_ constraints: CGSize) -> CGSize {
if constraints.width == 0 && constraints.height == 0 {
return self
}
let sx = constraints.width / width, sy = constraints.height / height
let s = sx != 0 && sy != 0 ? min(sx, sy) : max(sx, sy)
return CGSize(width: ceil(width * s), height: ceil(height * s))
}
}
extension URL {
func PDFCacheURL(_ pageNumber: Int, size: CGSize) -> URL? {
do {
let attributes = try FileManager.default.attributesOfItem(atPath: self.path)
if let fileSize = attributes[FileAttributeKey.size] as! NSNumber? {
if let fileDate = attributes[FileAttributeKey.modificationDate] as! Date? {
let hashables = self.path + fileSize.stringValue + String(fileDate.timeIntervalSince1970) + String(describing: size) + String(pageNumber)
let cacheDirectory = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0] + "/__PDF_CACHE__"
do {
try FileManager.default.createDirectory(atPath: cacheDirectory, withIntermediateDirectories: true, attributes:nil)
} catch {}
return URL(fileURLWithPath: cacheDirectory + "/" + String(format:"%2X", hashables.hash) + ".png")
}
}
} catch {}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment