【问题标题】:Extract a single page (or range of pages) from pdf data without loading the whole pdf (which takes too much RAM sometimes)从 pdf 数据中提取单个页面(或页面范围)而不加载整个 pdf(有时会占用太多 RAM)
【发布时间】:2019-02-07 04:39:42
【问题描述】:

在swift中使用PDFKit,可以使用PDFDocument打开pdf文件。 这很容易而且效果很好。但是我正在构建一个适合我需要的自定义 pdf 查看器(用于漫画书 pdf),但我遇到了一个问题。在查看器中,我不需要将整个 pdf 文件保存在内存中。我一次只需要几页。

此外,pdf 仅包含图像。没有文字或任何东西。

当实例化PDFDocument 时,整个 pdf 数据被加载到内存中。如果您有非常大的 pdf 文件(超过 1GB),这不是最佳选择(并且可能在某些设备上崩溃)。据我所知,PDFKit 无法仅加载 pdf 文档的一部分。

对此我能做些什么吗?我还没有找到可以做到这一点的 swift/obj-c 库(尽管我真的不知道搜索它的正确关键字)。

我的解决方法是使用 FileManager 预处理 pdf 并将每个页面保存为 .documents 目录(或类似文件)中的图像。这会产生大量文件,但会解决内存问题。不过,我不确定我是否喜欢这种方法。

更新:

所以我按照@Prcela 和@Sahil Manchanda 的建议做了。它现在似乎正在工作。

@yms:嗯,这确实是个问题。当只有图像时会发生这种情况吗? pdf中没有其他内容。

@Carpsen90:它们是本地的(保存在文档目录中)。

编辑:我没有接受下面的答案,也没有给它赏金。这是自动的。它不能解决问题。它仍然会将整个 PDF 加载到内存中!

【问题讨论】:

  • 也许这会有所帮助。看看 Surani 的简单回答:stackoverflow.com/questions/50195842/…
  • 这是一个有趣的想法。我会调查一下,看看我的情况是否可行。谢谢!
  • "在查看器中,我不需要将整个 pdf 文件保存在内存中。"实际上,除非 PDF 是线性化的,否则你会这样做。非线性 PDF 可能在第 100 页中定义了第 1 页所需的对象,并且文件的所有对象也可以压缩在单个容器对象中。线性化 PDF 旨在逐步加载。
  • @Quantm 而不是将它们保存为图像。您可以根据章节将 pdf 拆分为多个小 pdf。这样文件数量就会减少,您可以有效且高效地使用 PDFKit
  • pdf 是本地的吗?还是必须远程加载?

标签: ios swift pdf


【解决方案1】:

我知道如何在 PDFKit 中实现这一点。阅读文档后,有一个功能可以选择某些页面。如果您将其添加到 collectionFlowView 中,这可能会解决您的问题。

func selection(from startPage: PDFPage, atCharacterIndex startCharacter: Int, to endPage: PDFPage, atCharacterIndex endCharacter: Int) -> PDFSelection?

但是,当我读到您主要有图像时,还有另一个功能可以根据 CGPoints 提取 pdf 的部分内容:

func selection(from startPage: PDFPage, at startPoint: CGPoint, to endPage: PDFPage, at endPoint: CGPoint) -> PDFSelection?

也看看这个:https://developer.apple.com/documentation/pdfkit/pdfview

因为如果您只想查看页面而不进行任何注释编辑等,这可能是您所需要的。

我还准备了一些代码来提取下面的一页。希望对您有所帮助。

import PDFKit
import UIKit

class PDFViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let url = Bundle.main.url(forResource: "myPDF", withExtension: "pdf") else {fatalError("INVALID URL")}
        let pdf = PDFDocument(url: url)
        let page = pdf?.page(at: 10) // returns a PDFPage instance
        // now you have one page extracted and you can play around with it.
    }
}

编辑 1: 看看这个代码提取。我知道整个 PDF 都会被加载,但是这种方法可能更节省内存,因为 iOS 可能会在 PDFView 中更好地处理它:

func readBook() {

if let oldBookView = self.view.viewWithTag(3) {
    oldBookView.removeFromSuperview()
    // This removes the old book view when the user chooses a new book language
}

if #available(iOS 11.0, *) {
    let pdfView: PDFView = PDFView()
    let path = BookManager.getBookPath(bookLanguageCode: book.bookLanguageCode)
    let url = URL(fileURLWithPath: path)
    if let pdfDocument = PDFDocument(url: url) {
        pdfView.displayMode = .singlePageContinuous
        pdfView.autoScales = true
        pdfView.document = pdfDocument
        pdfView.tag = 3 // I assigned a tag to this view so that later on I can easily find and remove it when the user chooses a new book language
        let lastReadPage = getLastReadPage()

        if let page = pdfDocument.page(at: lastReadPage) {
            pdfView.go(to: page)
            // Subscribe to notifications so the last read page can be saved
            // Must subscribe after displaying the last read page or else, the first page will be displayed instead
            NotificationCenter.default.addObserver(self, selector: #selector(self.saveLastReadPage),name: .PDFViewPageChanged, object: nil)
        }
    }

    self.containerView.addSubview(pdfView)
    setConstraints(view: pdfView)
    addTapGesture(view: pdfView)
}

编辑 2:这不是 OP 正在寻找的答案。这也将整个 pdf 加载到内存中。 读取 cmets

【讨论】:

  • let pdf = PDFDocument(url: url)。这仍然会将整个 pdf 加载到内存中,这是我想要避免的。从文档中抓取页面不是问题。
  • 您是否尝试过在 Web 视图中打开 PDF 以查看它是否会为您提供类似的结果,这里有一个教程pspdfkit.com/blog/2016/opening-a-pdf-in-swift
  • 好吧,在我的情况下,Web 视图不起作用。此外,到目前为止,我尝试过的所有 Apple 默认的 pdf 查看课程都非常糟糕。 Web 视图可能使用相同的技术来呈现 pdf,这真的很糟糕。
  • 我会给 CocoaPods 一个镜头或 GitHub 搜索也许这可以帮助你
  • 试过了。没有什么对我真正有用。
猜你喜欢
  • 2018-05-05
  • 1970-01-01
  • 2022-10-18
  • 2019-05-30
  • 1970-01-01
  • 2021-09-24
  • 2018-01-15
  • 2020-09-06
  • 2012-09-06
相关资源
最近更新 更多