iOS提高PDF渲染速度

时间:2011-05-29 04:43:54

标签: iphone ios ipad pdf render

我正在编写一个管理用户文档的应用程序,并(最终)发布通过iPhone / iPad上的Web服务提供的PDF文件。这些几乎都是扫描的PDF文件,它们似乎真的让iOS设备陷入困境。

我提出的第一个解决方案是在UIWebView中简单地托管PDF。这对于“生成的”PDF文件非常有效,但不适用于扫描的PDF文件(我猜这里的区别是光栅与矢量?)。

我的下一个解决方案是实现一个UIDocumentInteractionController,据说可以增加快速性。我可以报告它确实比UIWebView更快,但它仍然慢得令人无法接受,即使在2页的小PDF文件中也是如此。 (另一方面,“自动打开另一个应用程序”功能,以及内置打印功能非常棒!)

我已经阅读了关于QuickLook框架的帖子或2,我打算调查一下,但我也偶然发现了一些关于CGPDFDocument类等的帖子。那些似乎对文档导航(la xPdf)有更好的控制,但我不知道从哪里开始。另外,我甚至不确定它是否为我正在做的事情提供了性能优势。

那么,第一个问题:在iPhone / iPad上渲染扫描的PDF文件的最快方法是什么?

第二个问题:扫描的PDF文件是由我公司生成的,因此我可以控制PDF生成设置。有人知道哪些设置可以提高基于图像的PDF文件的加载速度吗?

谢谢!

(顺便说一句:我今天已连续19个小时编码,所以如果我漫无目的或没有意义,请原谅我!:)

5 个答案:

答案 0 :(得分:6)

最快的解决方案是使用CGPDFDocument类编写自己的自定义pdf解析器和渲染框架。超高速pdf渲染的秘诀在于使用以下技术:

  • 将全尺寸页面脱屏呈现为图像。
  • 仅在某个缩放级别后激活CATiledLayer绘图。当用户以默认缩放级别查看您的pdf页面时,无需激活CATiledLayer绘图,因为它非常昂贵。只显示已经离屏的渲染图像。当用户开始放大时,您可以激活CATiledLayer。
  • 使用智能算法缓存屏幕外渲染的pdf页面。您可以将上一页和下一页缓存为离屏渲染图像。
  • 在快速设备(iPhone 4或更高版本以及iPad 2或更高版本)上,您可以启动后台作业,将所有页面移出屏幕并将其保存到磁盘。
  • 缓存常用的有关pdf页面的信息,如:原始矩形,旋转,旋转矩形等。
  • 您将使用大量CGPDFPageRef对象。重要的是要知道这将大大增加内存使用量。一个小技巧是在收到内存警告时关闭并重新打开CGPDFDocumentRef对象。

我在PDFTouch SDK for iOS中使用了上述所有技术,这是我开发的快速pdf渲染框架!

答案 1 :(得分:2)

您可能想尝试缩小图像尺寸。大型PDF正在推动iPad / iPhone达到极限。当然,这意味着您需要使用Quartz调用自己绘制/管理pdf。

通过适当的缓存可以提高速度。您可以在屏幕外渲染页面,并在不打开实际pdf的情况下显示它们 - 这要快得多。

答案 2 :(得分:1)

如果你绝望了,你可以重新处理服务器上的pdf文件,将它们变成简单的图像文件(与原始的pdf文件相关联),然后加载它们。这样就不需要进行“pdf”解析。然后,您可以在服务器上托管,或者如果音量较低,则包含在应用程序中。

基本上你需要一个服务器脚本来完成所有的重新处理并将新文件粘贴到一个特殊的文件夹中。也许你创建一个数据库来引用新文件。或者您可以为镜像原始pdf文件名的每个新文件创建目录名称。

答案 3 :(得分:1)

通过使用UIWebView呈现pdf,我们无法正确控制pdf。我们无法直接进入所需的页面。我们无法搜索特定的单词并突出显示。

最好使用CGPDF类(如CGPDFDocumentRef和CGPDFPageRef)来正确处理pdf文档。

使用这些类我们有两个选项来处理pdf。 1.单独提取pdf页面作为图像并使用UIImageView显示。 2.使用CGPDFPageRef提取每个页面的内容,并在运行时为每个页面创建pdf并显示在webview上。(更好地控制pdf和整洁的显示)

下面是将单个页面提取为图像的示例代码。

-(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;
}

答案 4 :(得分:0)

这是关于swift中简单快速的pdf渲染的2美分。

SwiftyPDF

  • 使用系统UIPageViewController进行分页
  • 使用UIScrollView缩放功能缩放
  • 通过将页面转换为占位符图像来快速呈现PDF
  • 缩放PDF页面并将其分成小块。平铺缓存到图像文件并在占位符图像上呈现(使用CATiledLayer)

仍为WIP