Created
April 20, 2021 12:15
-
-
Save fxm90/03d50754996f93888653e5fac6cd050a to your computer and use it in GitHub Desktop.
Playground showing how to convert a base 64 encoded PDF to an UIImage.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// PDFBase64ToImageViewController.swift | |
// | |
// Created by Felix Mau on 20.04.21. | |
// Copyright © 2021 Felix Mau. All rights reserved. | |
// | |
import PlaygroundSupport | |
import UIKit | |
import PDFKit | |
/// Icons made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com/). | |
/// Direct URL <https://www.flaticon.com/free-icon/settings_675579>. | |
let pdfAsBase64 = "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ht8S1JemX45xV2Td5faHqCh0r3H6evx8/AV9/ERmCmVuZHN0cmVhbQplbmRvYmoKNSAwIG9iagogICAxNzU2CmVuZG9iagozIDAgb2JqCjw8CiAgIC9FeHRHU3RhdGUgPDwKICAgICAgL2EwIDw8IC9DQSAxIC9jYSAxID4+CiAgID4+Cj4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlICUgMQogICAvUGFyZW50IDEgMCBSCiAgIC9NZWRpYUJveCBbIDAgMCAzODQgMzg0IF0KICAgL0NvbnRlbnRzIDQgMCBSCiAgIC9Hcm91cCA8PAogICAgICAvVHlwZSAvR3JvdXAKICAgICAgL1MgL1RyYW5zcGFyZW5jeQogICAgICAvSSB0cnVlCiAgICAgIC9DUyAvRGV2aWNlUkdCCiAgID4+CiAgIC9SZXNvdXJjZXMgMyAwIFIKPj4KZW5kb2JqCjEgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzCiAgIC9LaWRzIFsgMiAwIFIgXQogICAvQ291bnQgMQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJvZHVjZXIgKGNhaXJvIDEuMTYuMCAoaHR0cHM6Ly9jYWlyb2dyYXBoaWNzLm9yZykpCiAgIC9DcmVhdG9yIDxGRUZGMDA0OTAwNkUwMDZCMDA3MzAwNjMwMDYxMDA3MDAwNjUwMDIwMDAzMTAwMkUwMDMwMDAyRTAwMzIwMDIwMDAyODAwNjgwMDc0MDA3NDAwNzAwMDczMDAzQTAwMkYwMDJGMDA2OTAwNkUwMDZCMDA3MzAwNjMwMDYxMDA3MDAwNjUwMDJFMDA2RjAwNzIwMDY3MDAyOT4KICAgL0NyZWF0aW9uRGF0ZSAoRDoyMDIxMDQyMDA5MTM1OVopCj4+CmVuZG9iago3IDAgb2JqCjw8IC9UeXBlIC9DYXRhbG9nCiAgIC9QYWdlcyAxIDAgUgo+PgplbmRvYmoKeHJlZgowIDgKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAyMTYxIDAwMDAwIG4gCjAwMDAwMDE5NDMgMDAwMDAgbiAKMDAwMDAwMTg3MSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDE4NDggMDAwMDAgbiAKMDAwMDAwMjIyNiAwMDAwMCBuIAowMDAwMDAyNTA0IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgOAogICAvUm9vdCA3IDAgUgogICAvSW5mbyA2IDAgUgo+PgpzdGFydHhyZWYKMjU1NgolJUVPRgo=" | |
class PDFBase64ToImageViewController: UIViewController { | |
// MARK: - Config | |
private enum Config { | |
static let imageSize: CGFloat = 320 | |
} | |
// MARK: - Private methods | |
override func loadView() { | |
let view = UIView() | |
view.backgroundColor = .clear | |
// See extension on `String` below for the implementation. | |
let image = pdfAsBase64.convertPDFBase64StringToImage() | |
let imageView = UIImageView(image: image) | |
imageView.translatesAutoresizingMaskIntoConstraints = false | |
view.addSubview(imageView) | |
NSLayoutConstraint.activate([ | |
imageView.widthAnchor.constraint(equalToConstant: Config.imageSize), | |
imageView.heightAnchor.constraint(equalToConstant: Config.imageSize), | |
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), | |
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor), | |
]) | |
self.view = view | |
} | |
} | |
extension String { | |
/// Based on | |
/// [Convert a PDF to an Image in Swift](https://pspdfkit.com/blog/2020/convert-pdf-to-image-in-swift/) | |
func convertPDFBase64StringToImage() -> UIImage? { | |
guard | |
let imageData = Data(base64Encoded: self, options: .ignoreUnknownCharacters), | |
let document = PDFDocument(data: imageData), | |
let page = document.page(at: 0) | |
else { | |
return nil | |
} | |
// Fetch the page rect for the page we want to render. | |
let pageRect = page.bounds(for: .mediaBox) | |
let renderer = UIGraphicsImageRenderer(size: pageRect.size) | |
return renderer.image { ctx in | |
// Translate the context so that we only draw the `cropRect`. | |
ctx.cgContext.translateBy(x: -pageRect.origin.x, | |
y: pageRect.size.height - pageRect.origin.y) | |
// Flip the context vertically because the Core Graphics coordinate system starts from the bottom. | |
ctx.cgContext.scaleBy(x: 1, y: -1) | |
// Draw the PDF page. | |
page.draw(with: .mediaBox, to: ctx.cgContext) | |
} | |
} | |
} | |
// Present the view controller in the Live View window | |
PlaygroundPage.current.liveView = PDFBase64ToImageViewController() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment