webvew截屏

第一种方式

通过调用webview.capturePicture(),得到一个picture对象,根据图像的宽和高创建一个Bitmap,再创建一个canvas,绑定bitmap,最后用picture去绘制。

<code class="cpp"><span class="hljs-comment" style="color: rgb(136, 0, 0);">//获取Picture对象</span>
Picture picture = wv_capture.capturePicture();
<span class="hljs-comment" style="color: rgb(136, 0, 0);">//得到图片的宽和高(没有reflect图片内容)</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136);">int</span> width = picture.getWidth();
<span class="hljs-keyword" style="color: rgb(0, 0, 136);">int</span> height = picture.getHeight();
<span class="hljs-keyword" style="color: rgb(0, 0, 136);">if</span> (width > <span class="hljs-number" style="color: rgb(0, 102, 102);">0</span> && height > <span class="hljs-number" style="color: rgb(0, 102, 102);">0</span>) {
    <span class="hljs-comment" style="color: rgb(136, 0, 0);">//创建位图</span>
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = <span class="hljs-keyword" style="color: rgb(0, 0, 136);">new</span> Canvas(bitmap);
    <span class="hljs-comment" style="color: rgb(136, 0, 0);">//绘制(会调用native方法,完成图形绘制)</span>
    picture.draw(canvas);

}</code>

这种方式可以获取webview中已加载的所有数据图像,也就是长截屏的效果。这种方式在Android 4.4以下是没有问题的,但是在5.0以上就行不通了。capturePicture()方法在4.4中废弃掉了,官方建议使用onDrow()方法来获取webview的bitmap快照。具体实现如下:

<code class="cs"><span class="hljs-comment" style="color: rgb(136, 0, 0);">//获取webview缩放率</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136);">float</span> scale = wv_capture.getScale();
<span class="hljs-comment" style="color: rgb(136, 0, 0);">//得到缩放后webview内容的高度</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136);">int</span> webViewHeight = (<span class="hljs-keyword" style="color: rgb(0, 0, 136);">int</span>) (wv_capture.getContentHeight()*scale);
Bitmap bitmap = Bitmap.createBitmap(wv_capture.getWidth(),webViewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = <span class="hljs-keyword" style="color: rgb(0, 0, 136);">new</span> Canvas(bitmap);
<span class="hljs-comment" style="color: rgb(136, 0, 0);">//绘制</span>
wv_capture.draw(canvas);</code>

但是此时在5.0+上会发现,截取的快照只显示了webview中显示出来的那部分,没有显示出来的部分是空白的。通过google找到了原因,在5.0+版本上,Android对webview做了优化,旨在减少内存占用以提高性能。因此在默认情况下会智能的绘制html中需要绘制的部分,其实就是当前屏幕展示的html内容,因此会出现未显示的图像是空白的。解决办法是调用enableSlowWholeDocumentDraw()方法。这个方法需要在webview创建之前调用,在Activity里就是在setContentView前去调用,此方法会有显著的性能开销。

这里需要注意的是在传递webview的高度时,是通过缩放率计算的,这样就会算出绘制整个已加载的html内容所需的高度。如果没有这个缩放率,那么得到的快照就仅仅是这个html内容最上面的那一段。还有一个问题就是在5.0+系统上得到快照比较模糊,在其他版本上没有问题,不知道原因何在?

第二种方式

利用view的缓存功能。Android为了提高滚动等各方面的绘制速度,可以为每一个view建立一个缓存,使用 View.buildDrawingCache为自己的view建立相应的缓存, 这个cache就是一个bitmap对象。利用这个功能可以对整个屏幕视图进行截屏并生成Bitmap,也可以 获得指定的view的Bitmap对象。

因此对于webview来说也可以使用这种方式,在使用getDrawingCache()方法获取bitmap对象前,先开启webview的缓存功能.

<code class="objectivec">webView<span class="hljs-variable" style="color: rgb(102, 0, 102);">.setDrawingCacheEnabled</span>(<span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>);
...
Bitmap bitmap = webView<span class="hljs-variable" style="color: rgb(102, 0, 102);">.getDrawingCache</span>();</code>

需要注意的是,在上述情况下,这个缓存bitmap对象只有一个,因此每次获取的bitmap指向的是同一块地址空间的缓存对象,如果在使用完bitmap后就立即回收掉这个对象,那么再次获取当前view的缓存对象时就会得到null。所以要在Activity销毁时进行回收,所以开启缓存的话会有性能开销。

第三种方式

比较简单,通过获取当前window的DecorView,然后绘制Bitmap对象。

<code class="scala"><span class="hljs-type">View</span> view  = context.getWindow().getDecorView();
<span class="hljs-type">Bitmap</span> bitmap = <span class="hljs-type">Bitmap</span>.createBitmap(view.getWidth(), view.getHeight(), <span class="hljs-type">Bitmap</span>.<span class="hljs-type">Config</span>.<span class="hljs-type">ARGB_8888</span>);
<span class="hljs-type">Canvas</span> canvas = <span class="hljs-keyword" style="color: rgb(0, 0, 136);">new</span> <span class="hljs-type">Canvas</span>(bitmap);
view.draw(canvas);</code>

保存到文件

<code class="scala"><span class="hljs-keyword" style="color: rgb(0, 0, 136);">try</span> {
    <span class="hljs-type">String</span> fileName = <span class="hljs-type">Environment</span>.getExternalStorageDirectory().getPath()+<span class="hljs-string" style="color: rgb(0, 136, 0);">"/webview_capture4.jpg"</span>;
    <span class="hljs-type">FileOutputStream</span> fos = <span class="hljs-keyword" style="color: rgb(0, 0, 136);">new</span> <span class="hljs-type">FileOutputStream</span>(fileName);
    <span class="hljs-comment" style="color: rgb(136, 0, 0);">//压缩bitmap到输出流中</span>
    bitmap.compress(<span class="hljs-type">Bitmap</span>.<span class="hljs-type">CompressFormat</span>.<span class="hljs-type">JPEG</span>, <span class="hljs-number" style="color: rgb(0, 102, 102);">70</span>, fos);
    fos.close();
    <span class="hljs-type">Toast</span>.makeText(<span class="hljs-type">WebviewFromGetDecorView</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136);">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0);">"截屏成功"</span>, <span class="hljs-type">Toast</span>.<span class="hljs-type">LENGTH_LONG</span>).show();
    } <span class="hljs-keyword" style="color: rgb(0, 0, 136);">catch</span> (<span class="hljs-type">Exception</span> e) {
        <span class="hljs-type">Log</span>.e(<span class="hljs-type">TAG</span>, e.getMessage());
    }<span class="hljs-keyword" style="color: rgb(0, 0, 136);">finally</span> {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136);">if</span>(bitmap!=<span class="hljs-literal" style="color: rgb(0, 102, 102);">null</span>) {
            bitmap.recycle();
        }

    }</code>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值