Data/NSData类型存储的PDF数据转换为UIImage返回nil问题求助
问题根本原因
UIImage(data:) 方法仅支持PNG、JPEG、TIFF等标准位图格式的二进制数据,PDF是矢量文档格式,无法直接通过该方法解析加载,这是你始终得到nil的核心原因。
额外问题说明
你现有代码中使用固定2秒延时等待下载完成的逻辑非常不稳定,下载耗时受网络环境影响波动极大,建议直接将图片渲染逻辑放到下载完成的回调方法中执行,避免出现数据还没下载完就开始转换的问题。
解决方案代码实现
第一步:添加PDF转UIImage的工具方法
在你的ViewPDF类中添加如下通用转换方法,支持指定页码、按屏幕清晰度渲染:
func pdfDataToImage(_ data: Data, pageIndex: Int = 0, scale: CGFloat = UIScreen.main.scale) -> UIImage? { // 构造PDF文档对象 guard let provider = CGDataProvider(data: data as CFData), let pdfDocument = CGPDFDocument(provider), let pdfPage = pdfDocument.page(at: pageIndex + 1) else { // CGPDFDocument的页码从1开始计数 return nil } // 获取PDF页面原始尺寸,按屏幕缩放比计算渲染尺寸保证清晰度 let pageRect = pdfPage.getBoxRect(.mediaBox) let renderSize = CGSize(width: pageRect.width * scale, height: pageRect.height * scale) // 渲染PDF页为位图 let renderer = UIGraphicsImageRenderer(size: renderSize) let renderedImage = renderer.image { context in let cgContext = context.cgContext // 坐标系变换修正PDF上下颠倒的问题 cgContext.translateBy(x: 0, y: renderSize.height) cgContext.scaleBy(x: scale, y: -scale) cgContext.drawPDFPage(pdfPage) } return renderedImage }
第二步:修改下载回调逻辑
删掉test方法中2秒延时后的图片赋值逻辑,把转换渲染逻辑放到下载完成回调processDownloadedPDF中:
@objc func processDownloadedPDF(ticket: GTLRServiceTicket, finishedWithObject file: GTLRDataObject, error : NSError?) { if let error = error { print("Drive Download Error: \(error)") 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)) self.present(alert, animated: true) return } // 主线程更新UI DispatchQueue.main.async { [weak self] in guard let self = self, let pdfImage = self.pdfDataToImage(file.data) else { return } self.PDF.image = pdfImage } print("Drive Download Worked") }
如果你的PDF包含多页,只需循环调用pdfDataToImage方法传入不同的pageIndex参数,生成每页对应的图片后做分页展示即可。
内容的提问来源于stack exchange,提问作者Michael Szabo
相关产品推荐
相关产品推荐

