打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ZZ:Rendering PDF
http://www.cocoanetics.com/2010/06/rendering-pdf-is-easier-than-you-thought/


Rendering PDF is easier than you thought

We all know by now that Adobe is almost as evil as …, well let’s say they pioneered a couple of functionalities that where great for the longest time. One being the PDF format which is actually totally built into OSX everywhere. On OSX you’re able to print into a PDF without having to install extra software. Also iOS comes with PDF support and today we’ll look at how we can draw a PDF in a view.

How UIWebView sees it

The first idea you might have is to use UIWebView to display PDFs which is not difficult, just get the URL, make a NSURLRequest and pass this to a web view.

_webView = [[UIWebView alloc] initWithFrame:frame];_webView.delegate = self;_webView.autoresizingMask = UIViewAutoresizingFlexibleWidth |	UIViewAutoresizingFlexibleHeight; // we don't want interaction, full size_webView.scalesPageToFit = YES;_webView.userInteractionEnabled = NO;_webView.backgroundColor = [UIColor whiteColor]//fileURL is an NSURL to a PDF file[_webView loadRequest:[NSURLRequest requestWithURL:fileURL]];

But there is one drawback: you cannot really control how it will arrive on screen. For one thing, UIWebView draws a fat gray border and shadow which might somewhat mess up your UI design.

Wouldn’t it be great if you could draw the PDF somehow into a view? Yes, we can!

 

Drawing PDF Pages

Apple provides in CoreGraphics a whole set of functions prefixed CGPDF to deal with PDFs. The easiest method for drawing the first page of a PDF file I pieced together from the documentation like this. This is a regular view where I replaced the drawRect as follows:

- (void)drawRect:(CGRect)rect{	CGContextRef ctx = UIGraphicsGetCurrentContext()// PDF might be transparent, assume white paper	[[UIColor whiteColor] set];	CGContextFillRect(ctx, rect)// Flip coordinates	CGContextGetCTM(ctx);	CGContextScaleCTM(ctx, 1, -1);	CGContextTranslateCTM(ctx, 0, -rect.size.height)// url is a file URL	CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);	CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, 1)// get the rectangle of the cropped inside	CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);	CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,		rect.size.height / mediaRect.size.height);	CGContextTranslateCTM(ctx, -mediaRect.origin.x, -mediaRect.origin.y)// draw it	CGContextDrawPDFPage(ctx, page1);	CGPDFDocumentRelease(pdf);}

The part about the mediaRect is necessary because PDF pages are typically larger than what you really see on screen. There are usually some printing, color and crop marks outside of the content area. I managed to eliminate those by changing the transformation matrix of the CGContext.

The official method in the documentation is to use CGPDFPageGetDrawingTransform, but this has a catch: it won’t scale the image to be larger than 100% and instead center it on screen. So we build our own transform, ignoring the aspect ratio because we want to fill the view with that.

If the PDF is small enough to keep in memory you could also load it into an NSData object and access individual pages from it super fast. To read from data as opposed to providing an NSURL you change the code like this:

// data is an NSData object we filled with the PDF data from file beforeCGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)data]);CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(dataProvider);CGDataProviderRelease(dataProvider);

We’re using “toll-free bridging” to simply use our NSData instance where the function is expecting a CFDataRef, and of course if we have a method called SomethingCreate then we also have to have a SomethingRelease.

Conclusion

Having this ability to render PDF pages int any resolution gives you a great deal of flexibility. A great tool to have in your toolchest! You might even go as far as using PDFs as your main graphics container because it can contain both vector and bitmap graphics. In fact it’s the closest you can get to vector graphics on iOS.

Now please don’t go and make yet another PDF reader with this. With iBooks 1.1 soon supporting native PDF viewing that would make no sense.

Here are a couple other ideas:

  • An app that lets you keep your musical note sheets on your iPad. You could mark sections and specify their order and then choose between classical mode (one sheet per screen) or 1-pass mode, where the sections are flattened such that you don’t have to go back to repeats, but always play from left to right. Couple that with some fancy notes OCR to have the iPad play a bar before you. Maybe use audio clues on when to know to turn the page.
  • An app that lets you EDIT PDFs on the iPad, with cut/copy/paste support so that you can paste things on the iPad into a PDF-based scrapbook.
  • Make a presentation app similar to Prezi. You would load a PDF as basis and then you would record zoom levels, viewed rectangle and rotations along a user-defined path. Give presentation to external display.
  • Use a similar technique to render rich-text documents into reports that you can e-mail from your app.
  • Make an electronic version of a magazine similar to Wired, no need for Adobe’s weird Illustrator-to-App converter that makes half a GB apps.

If you’re interesting in partnering or co-developing these ideas please e-mail me.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
UIWebView 前进 后退 刷新 取消
webkit 作图流程解析(2)
iOS
gif图片保存和UIwebView显示代码实例 | 开发资源分享区
ios webview清除缓存
iPhone开发技巧之私有API(6)— 设置UIWebView中的User
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服