使用 Core Graphics 绘图时 PDF 文件显示不正确

Incorrect display of a PDF file when drawing using Core Graphics

面临使用Core Graphics Context绘图时部分PDF文件显示不正确的问题。背景块绘制正确但文本未显示。

借助在线工具对 PDF 文件进行的快速分析表明,所有文本都保存为单独的图片,分辨率和 dpi 都有些奇怪。但是标志图片没问题。

显示 pdf 文件的代码如下所示:

// #1 Load CGPDFDocument from file
guard let pdf = CGPDFDocument(NSURL(fileURLWithPath: fileURL.path)) else { return }

DispatchQueue.global(qos: .userInitiated).async { [weak self] in
    // #2 Enumerate a file pages
    for pageNumber in 1...pdf.numberOfPages {
        guard let pdfPage = pdf.page(at: pageNumber) else { return }

        var pageRect = pdfPage.getBoxRect(.mediaBox)
        // #3 Rendering current page
        var previewImage: UIImage?
        DispatchQueue.main.sync {
            let renderer = UIGraphicsImageRenderer(size: pageRect.size)
            previewImage = renderer.image { ctx in
                // ...
                // #4 Draw PDF page on the context
                ctx.cgContext.drawPDFPage(pdfPage)
            }
        }
        // ...
    }

此问题发生在 iPhone X (iOS 11) 和 iPhone 8 (iOS 11) 上。但是在其他设备上不会发生这种情况(包括带有 iOS 11 的其他设备)。

除非我弄错了 drawPDFPage 函数中发生了不正确的 pdf 处理。但是幕后发生了什么,是什么影响了结果?日志中没有错误。

你有遇到过类似的问题吗?此问题的解决方法是什么? 有没有其他方法可以从文件中提取 pdf 文件?

任何帮助都将不胜感激。

我找到了解决问题的办法。

从 iOS 11 开始,您可以使用 PDFKit 简单方便地处理此文件格式。在我的应用程序中从 PDF 页面获取 UIImage 的代码如下所示:

var pageImages: [UIImage] = []

if #available(iOS 11.0, *) {
    // iOS 11 approach
    // #1 Load PDFDocument using PDFKit
    if let pdfDocument = PDFDocument(url: fileURL) {
       // #2 Enumerate a file pages
        while pdfDocument.pageCount > index {
            guard let pdfPage = pdfDocument.page(at: index) else { continue }
            // #3 Rendering current pages thimbnail 
            pageImages.append(pdfPage.thumbnail(of: self.canvasSize, for: .mediaBox))
            index += 1
        }
    }
} else {
    // iOS 10 and earlier
    // #1 Load CGPDFDocument from file
    guard let pdf = CGPDFDocument(NSURL(fileURLWithPath: fileURL.path)) else { return }

    // #2 Enumerate a file pages
    for pageNumber in 1...pdf.numberOfPages {
        guard let pdfPage = pdf.page(at: pageNumber) else { return }

        var pageRect = pdfPage.getBoxRect(.mediaBox)
        // #3 Rendering current page
        var previewImage: UIImage?
        DispatchQueue.main.sync {
            let renderer = UIGraphicsImageRenderer(size: pageRect.size)
            previewImage = renderer.image { ctx in
                // ...
                // #4 Draw PDF page on the context
                ctx.cgContext.drawPDFPage(pdfPage)
            }
        }
        guard let preview = previewImage else { return }
        pageImages.append(preview)
    }

不要忘记添加 import PDFKit