Webview截屏三種方式

第一種方式

通過調(diào)用webview.capturePicture(),得到一個(gè)picture對象,根據(jù)圖像的寬和高創(chuàng)建一個(gè)Bitmap,再創(chuàng)建一個(gè)canvas,綁定bitmap,最后用picture去繪制。

//獲取Picture對象
Picture picture = wv_capture.capturePicture();
//得到圖片的寬和高(沒有reflect圖片內(nèi)容)
int width = picture.getWidth();
int height = picture.getHeight();
if (width > 0 && height > 0) {
    //創(chuàng)建位圖
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    //繪制(會調(diào)用native方法,完成圖形繪制)
    picture.draw(canvas);
 
}

這種方式可以獲取webview中已加載的所有數(shù)據(jù)圖像,也就是長截屏的效果。這種方式在Android 4.4以下是沒有問題的,但是在5.0以上就行不通了。capturePicture()方法在4.4中廢棄掉了,官方建議使用onDrow()方法來獲取webview的bitmap快照。具體實(shí)現(xiàn)如下:

//獲取webview縮放率
float scale = wv_capture.getScale();
//得到縮放后webview內(nèi)容的高度
int webViewHeight = (int) (wv_capture.getContentHeight()*scale);
Bitmap bitmap = Bitmap.createBitmap(wv_capture.getWidth(),webViewHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//繪制
wv_capture.draw(canvas);

但是此時(shí)在5.0+上會發(fā)現(xiàn),截取的快照只顯示了webview中顯示出來的那部分,沒有顯示出來的部分是空白的。通過google找到了原因,在5.0+版本上,Android對webview做了優(yōu)化,旨在減少內(nèi)存占用以提高性能。因此在默認(rèn)情況下會智能的繪制html中需要繪制的部分,其實(shí)就是當(dāng)前屏幕展示的html內(nèi)容,因此會出現(xiàn)未顯示的圖像是空白的。解決辦法是調(diào)用enableSlowWholeDocumentDraw()方法。這個(gè)方法需要在webview創(chuàng)建之前調(diào)用,在Activity里就是在setContentView前去調(diào)用,此方法會有顯著的性能開銷。

這里需要注意的是在傳遞webview的高度時(shí),是通過縮放率計(jì)算的,這樣就會算出繪制整個(gè)已加載的html內(nèi)容所需的高度。如果沒有這個(gè)縮放率,那么得到的快照就僅僅是這個(gè)html內(nèi)容最上面的那一段。還有一個(gè)問題就是在5.0+系統(tǒng)上得到快照比較模糊,在其他版本上沒有問題,不知道原因何在?

第二種方式

利用view的緩存功能。Android為了提高滾動等各方面的繪制速度,可以為每一個(gè)view建立一個(gè)緩存,使用 View.buildDrawingCache為自己的view建立相應(yīng)的緩存, 這個(gè)cache就是一個(gè)bitmap對象。利用這個(gè)功能可以對整個(gè)屏幕視圖進(jìn)行截屏并生成Bitmap,也可以 獲得指定的view的Bitmap對象。

因此對于webview來說也可以使用這種方式,在使用getDrawingCache()方法獲取bitmap對象前,先開啟webview的緩存功能.

webView.setDrawingCacheEnabled(true);
...
Bitmap bitmap = webView.getDrawingCache();

需要注意的是,在上述情況下,這個(gè)緩存bitmap對象只有一個(gè),因此每次獲取的bitmap指向的是同一塊地址空間的緩存對象,如果在使用完bitmap后就立即回收掉這個(gè)對象,那么再次獲取當(dāng)前view的緩存對象時(shí)就會得到null。所以要在Activity銷毀時(shí)進(jìn)行回收,所以開啟緩存的話會有性能開銷。

第三種方式

比較簡單,通過獲取當(dāng)前window的DecorView,然后繪制Bitmap對象。

View view  = context.getWindow().getDecorView();
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);

保存到文件

try {
    String fileName = Environment.getExternalStorageDirectory().getPath()+"/webview_capture4.jpg";
    FileOutputStream fos = new FileOutputStream(fileName);
    //壓縮bitmap到輸出流中
    bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
    fos.close();
    Toast.makeText(WebviewFromGetDecorView.this, "截屏成功", Toast.LENGTH_LONG).show();
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }finally {
        if(bitmap!=null) {
            bitmap.recycle();
        }

    }

具體demo猛戳這里:https://github.com/hsk256/WebviewCapture

參考:

http://developer.android.com/intl/zh-cn/reference/android/view/View.html

http://blog.csdn.net/a443453087/article/details/8563037

http://souly.cn/%E6%8A%80%E6%9C%AF%E5%8D%9A%E6%96%87/2016/01/05/DrawingCache%E8%A7%A3%E6%9E%90/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評論 25 708
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    小莊bb閱讀 3,668評論 3 25
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,875評論 0 19
  • Tips 由于WebView的用法實(shí)在太多,如果您只是想查詢某個(gè)功能的使用——建議Ctrl+F(Commad+F)...
    BugDev閱讀 7,916評論 11 109
  • 翼翼x閱讀 245評論 0 0

友情鏈接更多精彩內(nèi)容