IOS开发--------pdf渲染的小窍门

我们都知道,在iPhone/iPad显示pdf的基本方法有两个,一个是使用UIWebView直接加载pdf文件,另一个是使用Core Graphics进行渲染(姑且称之为CGPDF方法)。UIWebView的方法是简单,只需加载pdf,其他诸如放大翻页等问题通通交给UIWebView去头痛吧。但其缺点是性能较慢,功能有限,比如要实现搜索,添加笔记等功能就比较难。而使用CGPDF方法,功能就没有限制(虽然pdf解析方面,苹果提供的文档实在有限),使用Core Graphics进行渲染,性能上也比UIWebView要提高许多,只不过翻页,放大缩小等功能都需要自己实现

有关pdf放大缩小,翻页等功能可以使用UIScrollView实现,不在本文讨论的范围之内。笔者在项目中使用了CGPDF的过程中,曾遇到两个小问题,因此,在这里总结一下:

1. 页面放大后变得不清晰

先看看我程序中的渲染代码,可以放在- (void)drawRect:(CGRect)rect 或者 -(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-  ( void )drawRect : (CGRect )rect
{
    CGContextRef context  = UIGraphicsGetCurrentContext ( );

     // fill in the white background for pdf page
    CGContextSetRGBFillColor ( context, 1.0, 1.0, 1.0, 1.0  );
    CGContextFillRect ( context, CGContextGetClipBoundingBox ( context  ) );
    CGContextSaveGState (context );

     // Flip the context so that the PDF page is rendered
     // right side up.
    CGContextTranslateCTM ( context, 0.0, self.bounds.size.height  );
    CGContextScaleCTM ( context, 1.0,  -1.0  );

     // Scale the context so that the PDF page is rendered
     // at the correct size for the zoom level.
    CGAffineTransform pdfXfm  =
    CGPDFPageGetDrawingTransform ( _page.page, kCGPDFMediaBox, self.bounds, 0,  true  );
    CGContextConcatCTM ( context, pdfXfm  );

    CGContextSetInterpolationQuality (context, kCGInterpolationHigh );
    CGContextSetRenderingIntent (context, kCGRenderingIntentDefault );
    CGContextDrawPDFPage ( context, _page.page  );

    CGContextRestoreGState (context );
}


简单地说,这段代码就是使用Core Graphics进行pdf的渲染,可是我的pdf放大后为什么不清晰呢?先看看放大pdf后可以使其清晰的部分代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-  ( id )initWithPdfPage : (PDFPage * )page
{
     if  ( (self  =  [super initWithFrame :CGRectMake (0, 0, page.size.width, page.size.height ) ] ) )
     {
        CATiledLayer * layer  =  (CATiledLayer  * ) [self layer ];

        layer.levelsOfDetail  =  4;
        layer.levelsOfDetailBias  =  4;
        layer.tileSize  = CGSizeMake (1024.0, 1024.0 );
     }
     return self;
}

+  ( Class )layerClass
{
return  [CATiledLayer class ];
}


其秘诀就在CATiledLayer,简单地说就是CATiledLayer将不同等级的tiles(拼贴)缓存起来,而CGContextDrawPDFPage则根据最合适的放大等级将pdf渲染出来。

根据文档CATiledLayer可以更高效,高质量地渲染pdf文档,但我则遇到了第二个问题。

2. 页面渲染速度慢,而且呈块状渲染

简而言之就是pdf页面一块一块地慢慢渲染出来,效果非常不好。这是怎么回事?经过一番研究发现是CATiledLayer的动画效果在作怪。每个Tile的渲染据说都有0.25s的动画时间,其结果就是pdf文档一块一块地出现了。要怎样解决这个问题呢?最为直接的方法就是把0.25s的动画时间直接设置为0。下面是代码(采用继承CATiledLayer的方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@interface FastCATiledLayer  : CATiledLayer
@end

@implementation FastCATiledLayer
+ (CFTimeInterval )fadeDuration 
{
     return  0.0;
}

+  ( Class )layerClass 
{
     return  [FastCATiledLayer class ];   
}

-  ( id )initWithPdfPage : (PDFPage * )page 
{
     if  ( (self  =  [super initWithFrame :CGRectMake (0, 0, page.size.width, page.size.height ) ] ) ) 
     {
        FastCATiledLayer * layer  =  (FastCATiledLayer  * ) [self layer ];
        layer.levelsOfDetail  =  4;
    layer.levelsOfDetailBias  =  4;
    layer.tileSize  = CGSizeMake (1024.0, 1024.0 );
     }
     return self;
}

@end
注:PDFPage是我自己的一个类。

from:http://www.hksilicon.com/kb/cn/articles/26030/pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值