【问题标题】:Get a PDF/PNG as output from a UIWebView or UIView从 UIWebView 或 UIView 获取 PDF/PNG 作为输出
【发布时间】:2011-01-28 02:23:04
【问题描述】:

有没有办法获取UIWebView 的内容并将其转换为PDF 或PNG 文件?例如,我想通过在从 Safari 打印时选择 PDF 按钮来获得与 Mac 上可用的输出类似的输出。我假设这是不可能的/内置的,但希望我会感到惊讶并找到一种将内容从 web 视图获取到文件的方法。

谢谢!

【问题讨论】:

    标签: iphone objective-c cocoa-touch pdf png


    【解决方案1】:

    您可以在 UIView 上使用以下类别来创建 PDF 文件:

    #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
    

    坏消息:UIWebView 不会在 PDF 中创建漂亮的形状和文本,而是将自身呈现为 PDF 中的图像。

    【讨论】:

    • 感谢您的帖子。尽管 CGPDFContextCreateWithURL 没有正确创建上下文,但我遇到了一个问题。我尝试了几个不同的网址,但似乎没有任何改变。有什么想法吗?
    • CFURLRef 的创建方式存在错误。我修复了它,它现在应该适用于正确的文件 URL。
    • 使用这种方法渲染 UILabel 似乎会光栅化文本。如果您希望文本保持矢量化,请按照此处stackoverflow.com/questions/2209734/add-text-to-calayer 中的说明将它们直接绘制到图层中
    • 谁能告诉我如何访问在我的 viewController 中定义的这个方法?因为类别对我来说是全新的
    • @NikolaiRuhe 如果我们想渲染 UIWebView 内的内容,由于内容不适合框架内,该内容是可滚动的,上面描述的这个答案只渲染 UIWebView 框架内可见的内容。我尝试为 CGRect mediaBox = large hypothetical frame; 提供一个大的假设框架;但结果仍然相同。只有 webView 框架中可见的内容才会在 pdf 中呈现。有什么方法可以在 pdf 中呈现整个 webView 内容(即使是不可见但加载到 webview 中的任何内容)?
    【解决方案2】:

    从 Web 视图创建图像很简单:

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

    获得图像后,您可以将其保存为 PNG。

    也可以以非常相似的方式创建 PDF,但仅限于尚未发布的 iPhone OS 版本。

    【讨论】:

    • 我认为 CGPDF... API 从 iPhone OS 2.0 开始就存在了。
    • 是的,但我认为将图层渲染到 PDF 上下文中是新事物。
    • 这个答案几乎也有效。问题是页面之间的页面大小变化。有什么方法可以确定 webview 中内容的大小,以便我可以创建正确大小的上下文?
    • @St3fan 如果我们想在 UIWebView 内渲染内容,由于内容不适合框架内,该内容是可滚动的,上面描述的这个答案只渲染 UIWebView 框架内可见的内容。我尝试为 CGRect mediaBox = large hypothetical frame; 提供一个大的假设框架;但结果仍然相同。只有 webView 框架中可见的内容才会在 pdf 中呈现。有什么方法可以在 pdf 中呈现整个 webView 内容(即使是不可见但加载到 webview 中的任何内容)?
    • @mjdth 如果我们想在 UIWebView 内渲染内容,由于内容不适合框架内的内容而可滚动,那么上面描述的这个答案只会渲染 UIWebView 框架内可见的内容。我尝试为 CGRect mediaBox = large hypothetical frame; 提供一个大的假设框架;但结果仍然相同。只有 webView 框架中可见的内容才会在 pdf 中呈现。有什么方法可以在 pdf 中呈现整个 webView 内容(即使是不可见但加载到 webview 中的任何内容)?
    【解决方案3】:

    @mjdth,试试fileURLWithPath:isDirectory:URLWithString 也不适合我。

    @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
    

    【讨论】:

      【解决方案4】:

      下面的代码会将 UIWebView 的(完整)内容转换为 UIImage。

      渲染 UIImage 后,我将其以 PNG 格式写入磁盘以查看结果。
      当然,你可以随心所欲地使用 UIImage。

      UIImage *image = nil;
      CGRect oldFrame = webView.frame;
      
      // Resize the UIWebView, contentSize could be > visible size
      [webView sizeToFit];
      CGSize fullSize = webView.scrollView.contentSize;
      
      // Render the layer content onto the image  
      UIGraphicsBeginImageContext(fullSize);
      CGContextRef resizedContext = UIGraphicsGetCurrentContext();
      [webView.layer renderInContext:resizedContext];
      image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      
      // Revert the UIWebView back to its old size
      webView.frame = oldFrame;
      
      // Write the UIImage to disk as PNG so that we can see the result
      NSString *path= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.png"];
      [UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
      

      注意:确保 UIWebView 已完全加载(UIWebViewDelegate 或 loading 属性)。

      【讨论】:

        猜你喜欢
        • 2012-04-09
        • 1970-01-01
        • 2013-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多