views:

911

answers:

3

Is there any way to get the content of a UIWebView and convert it to a PDF or PNG file? I'd like to get similar output to that available on the Mac by selecting the PDF button when printing from Safari, for example. I'm assuming this isn't possible/built in yet, but hopefully I'll be surprised and find a way to get the content from a webview to a file.

Thanks!

+2  A: 

Creating a image from a web view is simple:

UIImage* image = nil;

UIGraphicsBeginImageContext(offscreenWebView_.frame.size);
{
    [offscreenWebView_.layer renderInContext: UIGraphicsGetCurrentContext()];
    image = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();

Once you have the image you can save it as a PNG.

Creating PDFs is also possible in a very similar way, but only on a yet unreleased iPhone OS version.

St3fan
I think that the CGPDF... API existed beginning from iPhone OS 2.0.
Nikolai Ruhe
Yeah but I thought rendering a layer into a PDF context was something new.
St3fan
This answer almost works too. The problem is the size of the page changes between pages. Is there any way to determine the size of the content in the webview so that I can create a correctly sized context?
mjdth
+3  A: 

You can use the following category on UIView to create a PDF file:

#import <QuartzCore/QuartzCore.h>

@implementation UIView(PDFWritingAdditions)

- (void)renderInPDFFile:(NSString*)path
{
    CGRect mediaBox = self.bounds;
    CGContextRef ctx = CGPDFContextCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path], &mediaBox, NULL);

    CGPDFContextBeginPage(ctx, NULL);
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -mediaBox.size.height);
    [self.layer renderInContext:ctx];
    CGPDFContextEndPage(ctx);
    CFRelease(ctx);
}

@end

Bad news: UIWebView does not create nice shapes and text in the PDF, but renders itself as an image into the PDF.

Nikolai Ruhe
Thanks for the post. I'm getting a problem though where the CGPDFContextCreateWithURL is not correctly creating the context. I've tried several different urls and it doesn't seem to change anything. Any ideas?
mjdth
There was a bug in how the CFURLRef was created. I fixed it and it should work now for proper file URLs.
Nikolai Ruhe
A: 

@mjdth, try fileURLWithPath:isDirectory: instead. URLWithString wasn't working for me either.

@implementation UIView(PDFWritingAdditions)

- (void)renderInPDFFile:(NSString*)path
{
    CGRect mediaBox = self.bounds;
    CGContextRef ctx = CGPDFContextCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path isDirectory:NO], &mediaBox, NULL);

    CGPDFContextBeginPage(ctx, NULL);
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -mediaBox.size.height);
    [self.layer renderInContext:ctx];
    CGPDFContextEndPage(ctx);
    CFRelease(ctx);
}

@end
Ford