Home > Software engineering >  Cannot convert Data to UIImage
Cannot convert Data to UIImage

Time:09-27

I am having trouble converting a PDF stored as Data & NSData into a UIImage. The pdf is generated by some APIs which spits it out as meme type PDF. There is nothing wrong with that data/PDF as I can attach it directly to an email and view it without and additional conversions or issues. I have done a lot of searching and it seems the following script is the way to go converting to UIImage.

var image = UIImage(data: data)

where data is the var that holds the PDF. This however does not work for me. :(

my code is shown below:


//file.data is where the PDF data is stored as Data

print(file.data)  //returns: 31108 bytes

store1 = file.data as NSData

print(store1) //returns: Optional(<25504446 2d312e34 0a2520e2.......>)

var image1 = UIImage(data: store1! as Data)

print(image1) //returns: nil


//similarly.....


print(file.data)  //returns: 31108 bytes

store2 = file.data

print(store2) //returns: Optional(31380 bytes)

var image2 = UIImage(data: store2!)

print(image2) //returns: nil

not sure where I'm going wrong here. Any thoughts?

thank you.

EDIT - Entire CODE

//
//  ViewPDF.swift
//  MA01
//
//  Created by Michael Szabo on 9/25/21.
//

import UIKit
import GoogleAPIClientForREST
import GoogleSignIn


class ViewPDF: UIViewController, GIDSignInDelegate {
    
    @IBOutlet weak var PDF: UIImageView!
    
    var spreadsheetID = ""
    var store:NSData? = nil
    var image:Data? = nil
    
    private let scopes = [kGTLRAuthScopeSheetsSpreadsheets, kGTLRAuthScopeSheetsDrive]
    private let service = GTLRDriveService()
    
    let signInButton = GIDSignInButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        
        GIDSignIn.sharedInstance().clientID = "private..."
        GIDSignIn.sharedInstance().delegate = self
        GIDSignIn.sharedInstance().scopes = scopes
        GIDSignIn.sharedInstance().restorePreviousSignIn()
        
    }
    

    @IBAction func test(_ sender: Any)
    {
        DispatchQueue.main.asyncAfter(deadline: .now()   0.0)
        { [self] in
            
            spreadsheetID = GlobalVariable.spreadsheetID
            exportFile()
            
                DispatchQueue.main.asyncAfter(deadline: .now()   2.0)
                { [self] in
                    
                    print("it started")
                   
                    var image = UIImage(data: store as! Data)
                    PDF.image = image
                 
                }
        }
    }
    
    
//========================================================================================================
//Export File As PDF
                    
    func exportFile() {
        print("started")
        
        service.authorizer = GIDSignIn.sharedInstance().currentUser.authentication.fetcherAuthorizer()

        let request = GTLRDriveQuery_FilesExport.queryForMedia(withFileId: spreadsheetID, mimeType: "application/pdf")
        let query = GTLRDriveQuery_FilesExport.queryForMedia(withFileId: spreadsheetID, mimeType: "application/pdf")
        
        
        service.executeQuery(query, delegate: self, didFinish: #selector(processDownloadedPDF(ticket:finishedWithObject:error:))
        )
        
        }

@objc func processDownloadedPDF(ticket: GTLRServiceTicket,
                          finishedWithObject file: GTLRDataObject,
                          error : NSError?) {
    if let error = error {
        print("Drive Download Error: \(error)")
        //self.navigationController?.navigationBar.stop()
        let alert = UIAlertController(title: "Google Drive Download Error", message:
            "Oops - Something went wrong! Error \(error.code): \(error.localizedDescription)", preferredStyle: .actionSheet)
        alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
        }))
        self.present(alert, animated: true, completion: nil)
        return
    }
    
    store = file.data as NSData
    
    
    //self.navigationController?.navigationBar.stop()
    print("Drive Download Worked")
    //Process downloaded file
    return
}
        
        
//=========================================================================================================
//Signin Authentication
    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
    withError error: Error!) {
    if let error = error {
    showAlert(title: "Authentication Error", message: error.localizedDescription)
    self.service.authorizer = nil
            } else {
    self.signInButton.isHidden = true
    //self.output.isHidden = false
    self.service.authorizer = user.authentication.fetcherAuthorizer()
            }
        }
        
        
// Display (in the UITextView) the names and majors of students in a sample
// spreadsheet:

                    
    func listMajors() {

        let range = "A1:Q"
        let query = GTLRSheetsQuery_SpreadsheetsValuesGet
                    .query(withSpreadsheetId: spreadsheetID, range:range)
                service.executeQuery(query) { (ticket, result, error) in
        if let error = error {
        self.showAlert(title: "Error", message: error.localizedDescription)
        return
                    }
        guard let result = result as? GTLRSheets_ValueRange else {
        return
                    }
        let rows = result.values!
        if rows.isEmpty {

        return
                    }
    //    self.output.text = "Number of rows in sheet: \(rows.count)"
                }
            }
            
        

        
    // Process the response and display output
        func displayResultWithTicket(ticket: GTLRServiceTicket,
    finishedWithObject result : GTLRSheets_ValueRange,
    error : NSError?) {
    if let error = error {
    showAlert(title: "Error", message: error.localizedDescription)
    return
            }
    var majorsString = ""
    let rows = result.values!
    if rows.isEmpty {
    //           output.text = "No data found."
    return
            }
            majorsString  = "Name, Major:\n"
    for row in rows {
    let name = row[0]
    let major = row[4]
                majorsString  = "\(name), \(major)\n"
            }
    //        output.text = majorsString
        }
        
        
        
    // Helper for showing an alert
        func showAlert(title : String, message: String)
    {
    let alert = UIAlertController(
    title: title,
    message: message,
    preferredStyle: UIAlertController.Style.alert
            )
    let ok = UIAlertAction(
    title: "OK",
    style: UIAlertAction.Style.default,
    handler: nil
            )
            alert.addAction(ok)
    present(alert, animated: true, completion: nil)
    }
    
    
}

CodePudding user response:

you could try something like this to get the image of a page in your pdf document.

        var img = UIImage()

        if let theUrl = Bundle.main.url(forResource: "welcome", withExtension: "pdf"),
           let doc = PDFDocument(url: theUrl),
           let thePage = doc.page(at: 0) {
            img = getUIImage(from: thePage)
        }
            
func getUIImage(from page: PDFPage) -> UIImage {
    let rect = page.bounds(for: PDFDisplayBox.mediaBox)
    let renderer = UIGraphicsImageRenderer(size: rect.size)
    let image = renderer.image(actions: { context in
        let cgContext = context.cgContext
        cgContext.setFillColor(gray: 1, alpha: 1)
        cgContext.fill(rect)
        cgContext.translateBy(x: 0, y: rect.size.height)
        cgContext.scaleBy(x: 1, y: -1)
        page.draw(with: PDFDisplayBox.mediaBox, to: cgContext)
    })
    return image
}

Then you can do the same for all the pages you want.

EDIT1:

given that file.data or store contains your pdf document, use this:

 if let doc = PDFDocument(data: file.data),
     let thePage = doc.page(at: 0) {
     img = getUIImage(from: thePage)
 }
  • Related