Converting uiimageview to pdf - Swift
Asked Answered
T

4

11

I am trying to create an iOS app using swift that will let the user either take a photo or choose an image from their gallery, and convert it to a pdf file that they are able to save to their phone. My code currently works to open either the camera or the gallery and choose an image, but I'm unable to convert it to pdf. Any tips would be really appreciated, thanks!

CameraViewController class

import UIKit

class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate
 {

    @IBOutlet weak var myImg: UIImageView!

    @IBAction func takePhoto(_ sender: AnyObject) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.camera
            imagePicker.allowsEditing = false
            self.present(imagePicker, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            myImg.contentMode = .scaleToFill
            myImg.image = pickedImage
        }
        picker.dismiss(animated: true, completion: nil)
    }

    @IBAction func savePhoto(_ sender: AnyObject) {
        let imageData = UIImagePNGRepresentation(myImg.image!)
        let compressedImage = UIImage(data: imageData!)
        UIImageWriteToSavedPhotosAlbum(compressedImage!, nil, nil, nil)

        let alert = UIAlertController(title: "Saved", message: "Your image has been saved", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
        alert.addAction(okAction)
        self.present(alert, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

GalleryViewController class

import UIKit

class GalleryViewController: UIViewController {

    @IBOutlet weak var myImg: UIImageView!

    @IBAction func pickPhoto(_ sender: Any) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
            imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
            imagePicker.allowsEditing = true
            self.present(imagePicker, animated: true, completion: nil)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            myImg.contentMode = .scaleToFill
            myImg.image = pickedImage
        }
        picker.dismiss(animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}
Thriller answered 11/5, 2017 at 10:25 Comment(0)
M
28

Answers Updated:

Since Apple introduced PDFKit to iOS 11.0, you can use the code below to convert uiimage to pdf, I only tried the osx below, but it should work the same way on iOS.

// Create an empty PDF document
let pdfDocument = PDFDocument()

// Load or create your UIImage
let image = UIImage(....)

// Create a PDF page instance from your image
let pdfPage = PDFPage(image: image!)

// Insert the PDF page into your document
pdfDocument.insert(pdfPage!, at: 0)

// Get the raw data of your PDF document
let data = pdfDocument.dataRepresentation()

// The url to save the data to
let url = URL(fileURLWithPath: "/Path/To/Your/PDF")

// Save the data to the url
try! data!.write(to: url)

================================================

Actually there're a lot similar questions and good enough answers. Let me try to answer this again.

Basically generating PDF is similar to the drawing in iOS.

  1. Create a PDF context and push it onto the graphics stack.
  2. Create a page .
  3. Use UIKit or Core Graphics routines to draw the content of the page.
  4. Add links if needed .
  5. Repeat steps 2, 3, and 4 as needed.
  6. End the PDF context to pop the context from the graphics stack and, depending on how the context was created, either write the resulting data to the specified PDF file or store it into the specified NSMutableData object.

So the most simple way would be something like this:

func createPDF(image: UIImage) -> NSData? {

    let pdfData = NSMutableData()
    let pdfConsumer = CGDataConsumer(data: pdfData as CFMutableData)!

    var mediaBox = CGRect.init(x: 0, y: 0, width: image.size.width, height: image.size.height)

    let pdfContext = CGContext(consumer: pdfConsumer, mediaBox: &mediaBox, nil)!

    pdfContext.beginPage(mediaBox: &mediaBox)
    pdfContext.draw(image.cgImage!, in: mediaBox)
    pdfContext.endPage()

    return pdfData
}

That created all the NSData for the PDF file, then we need to save the data to file:

let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let docURL = documentDirectory.appendingPathComponent("myFileName.pdf")

try createPDF(image: someUIImageFile)?.write(to: docURL, atomically: true)

Read more here: Generating PDF Content

Mickens answered 9/7, 2017 at 22:17 Comment(0)
H
7

in swift 5 using PDFKit : First Import PDFKit

Then use this array Extension :

import UIKit
import PDFKit


extension Array where Element: UIImage {
    
      func makePDF()-> PDFDocument? {
        let pdfDocument = PDFDocument()
        for (index,image) in self.enumerated() {
            let pdfPage = PDFPage(image: image)
            pdfDocument.insert(pdfPage!, at: index)
        }
        return pdfDocument
    }
}

and use this :

let imageArray = [UIImage(named: "1")!,UIImage(named: "2")!] let yourPDF = imageArray.makePDF()

Hbeam answered 16/4, 2020 at 13:34 Comment(0)
N
4

Swift 5 We will use UIGraphicsPDFRenderer() class and it will work for iOS 10+

        let image = results.croppedScan.image
        let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let docURL = documentDirectory.appendingPathComponent("Scanned-Docs.pdf")
        let outputFileURL: URL = docURL
        let imageBounds = CGRect(origin: .zero, size: image.size)
        let pdfRenderer = UIGraphicsPDFRenderer(bounds: imageBounds)
        do {
            try pdfRenderer.writePDF(to: outputFileURL) { context in
                context.beginPage()
                results.croppedScan.image.draw(in: imageBounds)
            }
        } catch {
            print("Could not create PDF file: \(error)")
        }
        print("save at ===\(outputFileURL)")
        //Show PDF in Controller
        let dc = UIDocumentInteractionController(url: outputFileURL)
        dc.delegate = self
        dc.presentPreview(animated: true)
Nazarene answered 24/3, 2021 at 8:11 Comment(0)
E
0
 func exportToPDF(_ uiImage:UIImage) {
    let outputFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("testing" + ".pdf")
    let pageSize = CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        
    let pdfRenderer = UIGraphicsPDFRenderer(bounds: CGRect(origin: .zero, size:  uiImage.size))
    DispatchQueue.main.async {
        do {
            let imageBounds = CGRect(origin: .zero, size: uiImage.size)
            try pdfRenderer.writePDF(to: outputFileURL, withActions: { (context) in
                context.beginPage()
                uiImage.draw(in: imageBounds)
              
            })
            print("wrote file to: \(outputFileURL.path)")
            var documentoPath = outputFileURL.path
            let fileManager = FileManager.default
            if fileManager.fileExists(atPath: documentoPath){
                            let documento = NSData(contentsOfFile: documentoPath)
                            let activityViewController: UIActivityViewController = UIActivityViewController(activityItems: [documento!], applicationActivities: nil)
                UIApplication.shared.windows.first?.rootViewController?.present(activityViewController, animated: true, completion: nil)
                        }
                        else {
                            print("wrote file to: No Document \(outputFileURL.path)")
                        }
        } catch {
            print("Could not create PDF file: \(error.localizedDescription)")
        }
        
       
    }
}
Eulalie answered 10/3, 2023 at 9:46 Comment(3)
This is basically a duplicate of an existing answer.Midwife
This is what works.Eulalie
But what does your answer provide that earlier answers don't? There is already an answer that shows how to use UIGraphicsPDFRenderer to create the PDF from an image.Midwife

© 2022 - 2024 — McMap. All rights reserved.