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)
}