适用于iPhone / iPad / iOs的快速和精简PDF查看器

最近有很多关于绘制PDF的问题。

是的,您可以使用UIWebView非常轻松地呈现PDF,但无法提供您期望从一个好的PDF查看器获得的性能和功能。

您可以将PDF页面绘制到CALayer或UIImage。 Apple甚至有示例代码来展示如何在Zoomable UIScrollview中绘制大型PDF

但同样的问题仍在继续。

UIImage方法:

  • UIImage PDF不像光学UIImage那样光学缩放。
  • PDFcontext生成UIImages的CPU和内存限制/阻止使用它来创建新的缩放级别的实时渲染。
  • CATiledLayer方法:

  • Theres是一个重要的开销(时间),将一个完整的PDF页面绘制到CALayer :可以看到单个tile呈现(即使使用tileSize调整)
  • CALayers不能提前做好准备(脱离屏幕)。
  • 一般来说,PDF阅读器在内存方面也相当重要。 甚至监控苹果的可缩放PDF示例的内存使用情况。

    在我目前的项目中,我正在开发一个PDF查看器,并在单独的线程中呈现页面的UIImage (这里也有问题!),并在scale为x1时呈现它。 一旦比例大于1, CATiledLayer渲染就会启动。 iBooks采取了类似的双重处理方法,就好像您滚动页面一样,在清晰版本出现之前,您可以看到较低分辨率的页面版本不到一秒钟。

    Im将页面的每一面都渲染为2焦点,这样PDF图像就可以在开始绘制图层之前对图层进行遮罩。当页面距焦点页面+2页时,页面会再次被销毁。

    有没有人有任何见解,无论改善图形PDF的性能/内存处理有多么微小或明显? 或在此讨论的任何其他问题?

    编辑:一些技巧(Credit Luke Mcneice,VdesmedT,Matt Gallagher,Johann):

  • 尽可能将任何介质保存到磁盘。

  • 如果在TiledLayers上渲染,请使用较大的tileSizes

  • 初始化经常使用的占位符对象的数组,另一种设计方法是另一种设计方法

  • 请注意,图像渲染速度比CGPDFPageRef

  • 使用NSOperations或GCD&Blocks提前准备页面。

  • 调用CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault); CGContextSetInterpolationQuality(ctx, kCGInterpolationHigh); CGContextSetRenderingIntent(ctx, kCGRenderingIntentDefault);CGContextDrawPDFPage之前减少绘图时的内存使用量

  • init'ing您NSOperations与docRef是一个坏主意(内存),包裹docRef到一个单例。

  • 取消不必要的NSOperations当你可以的时候,特别是如果他们将要使用内存的话,要注意让上下文保持开放!

  • 回收页面对象并销毁未使用的视图

  • 一旦你不需要它们,关闭所有打开的上下文

  • 在收到内存警告时释放并重新加载DocRef和任何页面缓存

  • 其他PDF特点:

  • 在PDF中获取链接(以及这里和这里)

  • 了解用于链接定位的PDF Rect

  • 转换PDF注释日期字符串

  • 获取链接的目标(从/Dest数组获取页码)

  • 获取目录

  • 文档标题和关键字

  • 获取原始文本(以及这里和这里和这里(定位聚焦))

  • 搜索(和这里)(不适用于所有的PDF文件(有些只显示奇怪的字符,我想这是一个编码问题,但我不确定) - 信誉BrainFeeder)

  • CALayer和离屏渲染 - 呈现下一页以进行快速/平滑显示

  • 文档

  • Quartz PDFObjects(用于元信息,注释,大拇指)
  • Abobe PDF Spec
  • 示例项目

  • Apple / ZoomingPDF - 缩放, UIScrollViewCATiledLayer
  • vfr / reader - 缩放,分页, UIScrollViewCATiledView
  • 眉毛/叶子 - 分页与漂亮的过渡
  • / skim - 看起来似乎(OSX的PDF阅读器/编辑器)

  • 我使用近似相同的方法构建了这样的应用程序,除了:

  • 我将生成的图像缓存在磁盘上,并提前在一个单独的线程中生成两到三个图像。
  • 我不覆盖UIImage ,而是在缩放为1时在图层中绘制图像。发出内存警告时,这些图块将自动释放。
  • 每当用户开始缩放时,我都会获取CGPDFPage并使用适当的CTM进行渲染。 在- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context中的代码如下所示:

    CGAffineTransform currentCTM = CGContextGetCTM(context);    
    if (currentCTM.a == 1.0 && baseImage) {
        //Calculate ideal scale
        CGFloat scaleForWidth = baseImage.size.width/self.bounds.size.width;
        CGFloat scaleForHeight = baseImage.size.height/self.bounds.size.height; 
        CGFloat imageScaleFactor = MAX(scaleForWidth, scaleForHeight);
    
        CGSize imageSize = CGSizeMake(baseImage.size.width/imageScaleFactor, baseImage.size.height/imageScaleFactor);
        CGRect imageRect = CGRectMake((self.bounds.size.width-imageSize.width)/2, (self.bounds.size.height-imageSize.height)/2, imageSize.width, imageSize.height);
        CGContextDrawImage(context, imageRect, [baseImage CGImage]);
    } else {
        @synchronized(issue) { 
            CGPDFPageRef pdfPage = CGPDFDocumentGetPage(issue.pdfDoc, pageIndex+1);
            pdfToPageTransform = CGPDFPageGetDrawingTransform(pdfPage, kCGPDFMediaBox, layer.bounds, 0, true);
            CGContextConcatCTM(context, pdfToPageTransform);    
            CGContextDrawPDFPage(context, pdfPage);
        }
    }
    

    问题是,方含的对象CGPDFDocumentRef 。 我同步我访问pdfDoc属性的部分,因为我释放它并在接收memoryWarnings时重新创建它。 看来CGPDFDocumentRef对象做了一些内部缓存,我没有找到如何摆脱。


    对于简单而有效的PDF查看器,当您只需要有限的功能时,您现在可以(iOS 4.0+)使用QuickLook框架:

    首先,您需要链接到QuickLook.framework#import <QuickLook/QuickLook.h>;

    之后,在viewDidLoad或任何延迟初始化方法中:

    QLPreviewController *previewController = [[QLPreviewController alloc] init];
    previewController.dataSource = self;
    previewController.delegate = self;
    previewController.currentPreviewItemIndex = indexPath.row;
    [self presentModalViewController:previewController animated:YES];
    [previewController release];
    

    iOS 11开始 ,您可以使用称为PDFKit的本机框架来显示和操作PDF。

    导入PDFKit后,您应该使用本地或远程URL初始化PDFView并将其显示在您的视图中。

    if let url = Bundle.main.url(forResource: "example", withExtension: "pdf") {
        let pdfView = PDFView(frame: view.frame)
        pdfView.document = PDFDocument(url: url)
        view.addSubview(pdfView)
    }
    

    在Apple Developer文档中阅读有关PDFKit的更多信息。

    链接地址: http://www.djcxy.com/p/36405.html

    上一篇: Fast and Lean PDF Viewer for iPhone / iPad / iOs

    下一篇: Bit Manipulation