无法将数据转换为 UIImage

Cannot convert Data to UIImage

我在将存储为数据和 NSData 的 PDF 转换为 UIImage 时遇到问题。 pdf 是由一些 API 生成的,这些 API 将其吐出为 meme 类型 PDF。 data/PDF 没有任何问题,因为我可以将它直接附加到电子邮件中并查看它,而无需额外的转换或问题。我做了很多搜索,似乎以下脚本是转换为 UIImage 的方法。

var image = UIImage(data: data)

其中数据是保存 PDF 的变量。然而,这对我不起作用。 :(

我的代码如下所示:


//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

不确定我哪里出错了。有什么想法吗?

谢谢。

编辑 - 完整代码

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

您可以尝试这样的操作来获取 pdf 文档中页面的图像。

        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
}

然后您可以对所有您想要的页面执行相同的操作。

编辑 1:

鉴于 file.datastore 包含您的 pdf 文档,请使用:

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