今天开发MarkEditor时要用到将 UIWebView 中显示的内容转为图片,方便转发到各个社交网络(Twiiter,Facebook,Weibo),这样内容就不受长度限制,类似于长微博。 之前关于视图转图片我知道可以通过 QuartzCore 里截图的形式,但是截图只能截取当前屏幕所显示的区域 (UIGraphicsGetCurrentContext()),而 UIWebView 的内容可能比屏幕长得多,在网上搜了一下,没有找到更好的方法,所有只用将 UIWebView 分屏截取,然后将截取的图片拼接成一张图片。

- (UIImage *)imageRepresentation{
CGSize boundsSize = self.bounds.size;
CGFloat boundsWidth = self.bounds.size.width;
CGFloat boundsHeight = self.bounds.size.height; CGPoint offset = self.scrollView.contentOffset;
[self.scrollView setContentOffset:CGPointMake(0, 0)]; CGFloat contentHeight = self.scrollView.contentSize.height;
NSMutableArray *images = [NSMutableArray array];
while (contentHeight > 0) {
UIGraphicsBeginImageContext(boundsSize);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[images addObject:image]; CGFloat offsetY = self.scrollView.contentOffset.y;
[self.scrollView setContentOffset:CGPointMake(0, offsetY + boundsHeight)];
contentHeight -= boundsHeight;
}
[self.scrollView setContentOffset:offset]; UIGraphicsBeginImageContext(self.scrollView.contentSize);
[images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) {
[image drawInRect:CGRectMake(0, boundsHeight * idx, boundsWidth, boundsHeight)];
}];
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return fullImage;
}

将 UIWebView 从头,contentOffset = (0, 0),开始截取webView.bounds.size.height高度的图片,然后将 _webView 可见区域下移继续截屏,这样将所有截取的图片按照顺序拼接,就能得到整个 UIWebView 显示内容的完整图片。(不知道有没有更好的方法)


本以为用同样的方法就能生成 PDF 文件

image

但是通过UIGraphics生成的 PDF 其实就是图片,文字都没法选中,而且质量也不高,所以继续查找其他方法。发现UIPrintPageRenderer可以实现渲染视图绘制的内容。

- (NSData *)PDFData{
UIViewPrintFormatter *fmt = [self viewPrintFormatter];
UIPrintPageRenderer *render = [[UIPrintPageRenderer alloc] init];
[render addPrintFormatter:fmt startingAtPageAtIndex:0];
CGRect page;
page.origin.x=0;
page.origin.y=0;
page.size.width=600;
page.size.height=768; CGRect printable=CGRectInset( page, 50, 50 );
[render setValue:[NSValue valueWithCGRect:page] forKey:@"paperRect"];
[render setValue:[NSValue valueWithCGRect:printable] forKey:@"printableRect"]; NSMutableData * pdfData = [NSMutableData data];
UIGraphicsBeginPDFContextToData( pdfData, CGRectZero, nil ); for (NSInteger i=0; i < [render numberOfPages]; i++)
{
UIGraphicsBeginPDFPage();
CGRect bounds = UIGraphicsGetPDFContextBounds();
[render drawPageAtIndex:i inRect:bounds]; }
UIGraphicsEndPDFContext();
return pdfData;
}

通过这种方式生成的 PDF 质量高,与浏览器“打印”功能显示出的内容一样

image1


代码已上传 github (https://github.com/tracy-e/UIWebViewToFile)

======== 全文完 ============

Posted by XiaoYi_HD - 6月 10 2013
如需转载,请注明: 本文来自 Esoft Mobile

将UIWebView显示的内容转为图片和PDF的更多相关文章

  1. Linux入门(13)——Ubuntu16.04下将图片和pdf互转

    Ubuntu16.04下将图片和pdf互转 将图片转为PDF: convert 图片 PDF convert pic.jpg pic.pdf 将PDF转为图片: convert PDF 图片 conv ...

  2. Java:PPT(X)转图片、PDF和SVG

    (一) 简介: 工作中,PowerPoint文档有时需要被转换为PDF/图像文件来存档.因为PDF或图片的页面布局是固定的,很难被修改且能被大多数设备打开,所以PDF或者图片比起PowerPoint格 ...

  3. 如何给wordpress首页自动显示文章内容的第一个图片

    敏捷个人手机应用中使用到的数据来源于wordpress中,因为自己写的页面,所以可以自己写代码获取文章内容的第一个图片作为文章缩略图来显示,这样用户看到首页时图文并茂,感觉会好一些. 现在后台简单的使 ...

  4. jQuery:实现图片按需加载的方法,当要显示内容的高度超过了页面的高度,按需加载,根据滚动条的位置来判断页面显示的内容

    实现图片按需加载的方法,当要显示内容的高度超过了页面的高度,按需加载,根据滚动条的位置来判断页面显示的内容 这个类似于京东或淘宝页面,根绝页面的滚动,显示下面的内容 如下图所示,一开始并不是所有的图片 ...

  5. C#实现 word、pdf、ppt 转为图片

    office word文档.pdf文档.powerpoint幻灯片是非常常用的文档类型,在现实中经常有需求需要将它们转换成图片 -- 即将word.pdf.ppt文档的每一页转换成一张对应的图片,就像 ...

  6. winform里面网页显示指定内容

    今天有个同事问了一下我,怎么在winform里面打开网页啊?我们都是基于C/S的开发,很少接触winform,所以我当时就懵了,实在不知道怎么回答,所以索性说不知道.但是我又想了想,这个应该是个很简单 ...

  7. [小知识]不显示没有内容的UITableViewCell

    开发过程中常常使用到UITableView,当tableView的内容不足一屏时,若设置了talbeView的高度为屏幕高度,就会出现没有内容的cell显示出来,效果非常不好看,要想让没有内容的cel ...

  8. JQuery - 留言之后,不重新加载数据,直接显示发表内容

    留言板中,发表信息的时候,使用Ajax存储到后台数据库,如果存储成功,不重新加载数据库,直接显示发表内容. 代码: var Nicehng = ''; var kkimgpath = ''; var ...

  9. word、pdf、ppt 转为图片

    office word文档.pdf文档.powerpoint幻灯片是非常常用的文档类型,在现实中经常有需求需要将它们转换成图片 -- 即将word.pdf.ppt文档的每一页转换成一张对应的图片,就像 ...

随机推荐

  1. 你不需要jQuery(五)

    什么不用jQuery?因为它让你的网站体积变得臃肿.你的网站并不真的需要jQuery,不需要它带来的额外体积.带宽和加载时间. 用原生JavaScript简单实现jQuery提供的功能和方法 查找.选 ...

  2. maven添加jar包依赖

    maven的东西使用了一段时间,但是每次使用都多少有点含糊,所以总结一下. 目前主要使用是在jar包的控制上 原理: 在本地,指定一个文件夹,便是maven的仓库,maven会从远程的中央仓库中下载你 ...

  3. 算法导论_ch2

    Ch2算法基础 whowhoha@outlook.com 2.1 插入排序 输入:n个数的一个序列〈a1,a2,…,an〉. 输出:输入序列的一个排列〈a′1,a′2,…,a′n〉,满足a′1≤a′2 ...

  4. uva 10562

    二叉树的先序遍历  这个还是比较简单的 ~~ /************************************************************************* &g ...

  5. uva 10608

    简单并查集  水水..... #include <cstdio> #include <cstring> #define maxn 30005 int fa[maxn],ans[ ...

  6. Spring/Hibernate 应用性能优化的7种方法

    对于大多数典型的 Spring/Hibernate 企业应用而言,其性能表现几乎完全依赖于持久层的性能.此篇文章中将介绍如何确认应用是否受数据库约束,同时介绍七种常用的提高应用性能的速成法.本文系 O ...

  7. VARCHAR2转换为CLOB碰到ORA-22858错误

    近日工作中发现有一张表的字段类型建错了,本应是BLOB类型却被别人建成了VARCHAR2(200),修改时oracle却提示“ORA-22858 invalid alteration of datat ...

  8. Linux---弹球游戏

    ReadMe: 弹球游戏按键说明(注意大小写): Q End Up Game 游戏停止 P Play Again  再玩一次 f 速度x轴方向减速 s 速度x轴方向加速 F 速度y轴方向减速 S 速度 ...

  9. C++ 通过对象方式 、指针方式两种方式去访问成员变量(属性或者方法)

    准备 1.在VS中新建一个项目-Viscal C++ ---常规--空项目 2.建立一个.h的头文件 定义一个类 声明其成员(C#中的属性和方法) #include<iostream> # ...

  10. java List 去重(两种方式)

    方法一: 通过Iterator 的remove方法 Java代码  public void testList() { List<Integer> list=new ArrayList< ...