[英]iOS improve PDF render speed
I'm writing an app that manages documents for a user and (eventually) posts PDF files served out through a web service on the iPhone/iPad.我正在编写一个为用户管理文档的应用程序,并(最终)发布通过 iPhone/iPad 上的 web 服务提供的 PDF 文件。 These are almost exclusively scanned PDF files, and they appear to REALLLLLY bog down the iOS device.这些几乎完全是扫描的 PDF 文件,它们似乎真的让 iOS 设备陷入困境。
The first solution I came up with was to simply host the PDF in a UIWebView.我想出的第一个解决方案是简单地将 PDF 托管在 UIWebView 中。 This works really, really well for "generated" PDF files, but NOT for scanned PDF files (I'm guessing the difference here is raster vs. vector?).这对于“生成的” PDF 文件非常非常有效,但不适用于扫描的 PDF 文件(我猜这里的区别是光栅与矢量?)。
My next solution was to implement a UIDocumentInteractionController, which was said to increase snappiness.我的下一个解决方案是实现一个 UIDocumentInteractionController,据说可以增加敏捷性。 I can report that it does, indeed, seem to be faster than UIWebView, but it's still unacceptably slow, even on smallish, 2 page PDF files.我可以报告它确实似乎比 UIWebView 快,但它仍然慢得令人无法接受,即使在较小的 2 页 PDF 文件上也是如此。 (On a side note, the "auto-open-in-another-app" feature, along with built-in printing is super slick!) (附带说明,“在另一个应用程序中自动打开”功能以及内置打印功能非常棒!)
I've read a post or 2 about the QuickLook framework, and I plan to look into that, but I've also stumbled across a few posts talking about CGPDFDocument classes and such.我已经阅读了一篇或两篇关于 QuickLook 框架的文章,我打算研究一下,但我也偶然发现了一些关于 CGPDFDocument 类等的文章。 Those seem to have a finer control over document navigation (a la xPdf), but I have no idea where to start with that.那些似乎对文档导航(la xPdf)有更好的控制,但我不知道从哪里开始。 Plus, I'm not even sure if it offers a performance benefit for what I'm doing.另外,我什至不确定它是否为我正在做的事情提供了性能优势。
So, first question: what's the fastest way to render scanned PDF files on the iPhone/iPad?那么,第一个问题:在 iPhone/iPad 上渲染扫描的 PDF 文件的最快方法是什么?
Second question: The scanned PDF files are generated by my company, so I have some control over the PDF generation settings.第二个问题:扫描的PDF文件是我公司生成的,所以我对PDF的生成设置有一定的控制权。 Does anybody know what settings might improve load speed for image-based PDF files?有谁知道哪些设置可以提高基于图像的 PDF 文件的加载速度?
Thanks!谢谢!
(By the way: I've been coding for 19 hours straight today, so if I rambled or didn't make sense, please forgive me: :) ) (顺便说一句:我今天已经连续编码了 19 个小时,所以如果我漫无目的或没有意义,请原谅我::))
The fastest solution will be to write your own custom pdf parser and rendering framework using the CGPDFDocument classes.最快的解决方案是使用 CGPDFDocument 类编写您自己的自定义 pdf 解析器和呈现框架。 The secret to superfast pdf rendering is using techniques like:超快 pdf 渲染的秘诀是使用以下技术:
I used all of the above mentioned techniques in PDFTouch SDK for iOS which is a fast pdf rendering framework developed by me!我在PDFTouch SDK for iOS中使用了上述所有技术,这是我开发的快速 pdf 渲染框架!
You may wanna try to reduce image size.您可能想尝试减小图像大小。 Large PDFs are really pushing the iPad/iPhone to its limits.大型 PDF 确实将 iPad/iPhone 推向了极限。 Of course this means that you need to draw/manage the pdf yourself, with Quartz calls.当然,这意味着您需要通过 Quartz 调用自己绘制/管理 pdf。
More speed is possible with proper caching.使用适当的缓存可以提高速度。 You can render pages off-screen, and display them without opening the actual pdf - which is much, much faster.您可以在屏幕外渲染页面,并在不打开实际 pdf 的情况下显示它们——这要快得多。
if you get desperate you could re-process the pdf files on your server to turn them into simple image files (associated with the original pdf files) then load those.如果您感到绝望,您可以重新处理服务器上的 pdf 文件,将它们转换为简单的图像文件(与原始 pdf 文件相关联)然后加载这些文件。 that way no "pdf" parsing needs to take place.这样就不需要进行“pdf”解析。 and then you can host on the server or include as part of the app if the volume is low.然后您可以在服务器上托管或在音量较低时将其作为应用程序的一部分包含在内。
basically you'd need a server script that does all the re-processing and sticks the new files into a special folder.基本上,您需要一个服务器脚本来执行所有重新处理并将新文件粘贴到一个特殊文件夹中。 maybe you make a database to reference the new files.也许您创建一个数据库来引用新文件。 or maybe you create a directory name for each new file that mirrors the original pdf file name.或者,您可以为每个新文件创建一个目录名,以反映原始 pdf 文件名。
By using UIWebView to render the pdf, we will not get proper control over the pdf.通过使用 UIWebView 渲染 pdf,我们将无法正确控制 pdf。 like we cannot go to the desired page directly.就像我们不能 go 直接到所需的页面。 and we cannot search a particular word and highlight.我们无法搜索特定的单词并突出显示。
its better to use CGPDF classes like CGPDFDocumentRef and CGPDFPageRef to handle the pdf documents properly.最好使用 CGPDFDocumentRef 和 CGPDFPageRef 等 CGPDF 类来正确处理 pdf 文档。
Using these classes we have two options to handle the pdf's.使用这些类,我们有两个选项来处理 pdf。 1. extracting the pdf pages as images individually and display using UIImageView. 1. 将 pdf 页面单独提取为图像并使用 UIImageView 显示。 2. extract the content of each page using CGPDFPageRef and create pdf for each page at runtime and display on to the webview.(better control control over pdf and neat display) 2.使用CGPDFPageRef提取每个页面的内容并在运行时为每个页面创建pdf并显示到webview上。(更好的控制控制Z437175BA4191210EE004E1D93749和显示)
below is the sample code to extract individual page as an image.下面是将单个页面提取为图像的示例代码。
-(UIImage *)getPage : (NSString*) filePath{
const char *myBuffer = (const char*)filePath; // PDF Path
CFStringRef urlString = (CFStringRef)myBuffer;
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, urlString, 2, NO);
CGPDFDocumentRef myDocumentRef = CGPDFDocumentCreateWithURL(url);
CGPDFPageRef myPageRef = CGPDFDocumentGetPage(myDocumentRef, 1);
CGRect pdfcropBox = CGPDFPageGetBoxRect(myPageRef,kCGPDFCropBox); //kCGPDFCropBox
UIGraphicsBeginImageContext (pdfcropBox.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM (context,0,pdfcropBox.size.height);// [self pageRect].origin.x,[self pageRect].origin.y+[self pageRect].size.height); //320);
// scale 1:1 100%
CGContextScaleCTM (context, 1.0, -1.0);
CGContextSaveGState (context);
CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(myPageRef, kCGPDFCropBox, CGRectMake(0, 0, pdfcropBox.size.width,pdfcropBox.size.height), 0, true); //
CGContextConcatCTM (context, pdfTransform);
CGContextDrawPDFPage (context, myPageRef);
CGContextRestoreGState (context);
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext ();
CGPDFDocumentRelease (myDocumentRef);
//CGPDFPageRelease(myPageRef);
//myPageRef = nil;
myDocumentRef = nil;
urlString = nil;
url = nil;
return resultingImage;
}
Here are my 2 cents about easy and fast pdf rendering in swift.这是我关于在 swift 中简单快速的 pdf 渲染的 2 美分。
Still WIP仍然在制品
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.