关于PDF的读取与绘制

 

本文方法参考了:官方文档。见A function that draw a PDF page的代码部分:
void MyDisplayPDFPage (CGContextRef myContext,
                    size_t pageNumber,
                    const char *filename)
{
    CGPDFDocumentRef document;
    CGPDFPageRef page;
    CGRect box;
 
    document = MyGetPDFDocumentRef (filename);// 1
    page = CGPDFDocumentGetPage (document, pageNumber);// 2
    CGContextDrawPDFPage (myContext, page);// 3
    CGPDFDocumentRelease (document);// 4
}
可见,编写读取的代码很简单,只需给定三个参数即可。后两个很容易,pageNumber是int型的数字,表示第几页,filename是肯定知道的。问题是如何获取CGContextRef,这个类型对象是用于绘图的上下文对象引用,没有它就没法绘制到屏幕界面上。

查了一下文档,特别是这个帖子:

看来要继承UIView,才能得到当前视图的Context。基本思路是覆盖UIView的drawRect方法,在该方法中:

1
2
3
- (void)drawRect:(CGRect)rect {
    [self drawInContext:UIGraphicsGetCurrentContext()];
}

调用UIGraphicsGetCurrentContext方法,将当前的图形上下文设置给调用PDF的代码。drawRect方法会在iOS系统绘制界面的时候调用。

下面来说说编写代码的步骤,首先创建一个view-based application,然后,通过IB,设置控制器到view的关联。

以下不再用IB了,PDF的UIView是通过程序生成的。

创建PdfView类,是UIView的子类。头文件:

1
2
3
4
5
6
7
8
9
#import <Foundation/Foundation.h>
 
@interface PdfView : UIView {
    CGPDFDocumentRef pdf;
}
 
-(void)drawInContext:(CGContextRef)context;
 
@end

里面带一个成员,pdf,代表pdf文档对象的引用。一个方法,用于根据图形上下文在视图中绘制制定的pdf页面。

m文件:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    #import "PdfView.h"
 
    @implementation PdfView
    - (id)initWithFrame:(CGRect)frame{
 
        if ((self = [super initWithFrame:frame]))
        {
            // Initialization code
            if(self != nil)
            {
                CFURLRef pdfURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("test.pdf"), NULL, NULL);
                pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
                CFRelease(pdfURL);
            }
        }
        return self;
    }
 
    -(void)drawInContext:(CGContextRef)context
    {
        // PDF page drawing expects a Lower-Left coordinate system, so we flip the coordinate system
        // before we start drawing.
        CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
 
        // Grab the first PDF page
        CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
        // We’re about to modify the context CTM to draw the PDF page where we want it, so save the graphics state in case we want to do more drawing
        CGContextSaveGState(context);
        // CGPDFPageGetDrawingTransform provides an easy way to get the transform for a PDF page. It will scale down to fit, including any
        // base rotations necessary to display the PDF page correctly.
        CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, self.bounds, 0, true);
        // And apply the transform.
        CGContextConcatCTM(context, pdfTransform);
        // Finally, we draw the page and restore the graphics state for further manipulations!
        CGContextDrawPDFPage(context, page);
        CGContextRestoreGState(context);
    }
 
    - (void)drawRect:(CGRect)rect {
        [self drawInContext:UIGraphicsGetCurrentContext()];
    }

在这里使用的pdf文档,是放在项目的Resources目录下的。

再往下,就是在Controller中通过程序创建PdfView实例,并将它关联为Controller根视图的子视图:

1
2
3
4
5
6
7
8
9
- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = CGRectMake(0, 0, 768, 1000);
 
    PdfView *pdfView = [[PdfView alloc] initWithFrame:frame];
    pdfView.backgroundColor=[UIColor whiteColor];
    [self.view addSubview:pdfView];
 
}

这里因为是使用iPad,因此长宽是1000(上面留点空间)和768。另外,需要设置底色,默认情况下底色是黑色的,和黑体的文字在一起就显示不出文字了,我设置的是白色:

pdfView.backgroundColor=[UIColor whiteColor];

这样就可以了,而且中文啥的都没问题。

 

 

http://stackoverflow.com/questions/2643150/load-pdf-into-layer-offscreen

posted @ 2013-06-21 16:21  yingkong1987  阅读(563)  评论(0编辑  收藏  举报