Get a PDF/PNG as output from a UIWebView or UIView

13,108

Solution 1

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.

Solution 2

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.

Share:
13,108
mjdth
Author by

mjdth

Updated on June 08, 2022

Comments

  • mjdth
    mjdth almost 2 years

    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!

  • Nikolai Ruhe
    Nikolai Ruhe about 14 years
    I think that the CGPDF... API existed beginning from iPhone OS 2.0.
  • Stefan Arentz
    Stefan Arentz about 14 years
    Yeah but I thought rendering a layer into a PDF context was something new.
  • mjdth
    mjdth about 14 years
    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
    mjdth about 14 years
    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?
  • Nikolai Ruhe
    Nikolai Ruhe over 13 years
    There was a bug in how the CFURLRef was created. I fixed it and it should work now for proper file URLs.
  • Admin
    Admin over 12 years
    Rendering UILabels with this method seem to rasterize the text. If you want your text to remain vectorized, draw them directly into the layer as described here stackoverflow.com/questions/2209734/add-text-to-calayer
  • Raj
    Raj over 11 years
    Can anyone tell me how to access this method defined in category in my viewController ? coz category is completely new to me
  • SayeedHussain
    SayeedHussain over 11 years
    @NikolaiRuhe If we want to render the content inside a UIWebView which is scrollable because of content not fitting inside the frame, this answer described above renders just what is visible within the UIWebView frame. I have tried giving a large hypothetical frame for CGRect mediaBox = large hypothetical frame; but still the result is same. Only what's visible in the webView frame gets rendered in the pdf. Any way we can render the whole webView content (even whatever is not visible but loaded inside webview) in the pdf?
  • SayeedHussain
    SayeedHussain over 11 years
    @St3fan If we want to render the content inside a UIWebView which is scrollable because of content not fitting inside the frame, this answer described above renders just what is visible within the UIWebView frame. I have tried giving a large hypothetical frame for CGRect mediaBox = large hypothetical frame; but still the result is same. Only what's visible in the webView frame gets rendered in the pdf. Any way we can render the whole webView content (even whatever is not visible but loaded inside webview) in the pdf?
  • SayeedHussain
    SayeedHussain over 11 years
    @mjdth If we want to render the content inside a UIWebView which is scrollable because of content not fitting inside the frame, this answer described above renders just what is visible within the UIWebView frame. I have tried giving a large hypothetical frame for CGRect mediaBox = large hypothetical frame; but still the result is same. Only what's visible in the webView frame gets rendered in the pdf. Any way we can render the whole webView content (even whatever is not visible but loaded inside webview) in the pdf?
  • Nikolai Ruhe
    Nikolai Ruhe over 11 years
    @crypticcoder To do that you have to set the bounds of the view to your desired dimensions before calling above method.