Webview截圖三種方式
第一種方式
通過呼叫webview.capturePicture(),得到一個picture物件,根據影象的寬和高建立一個Bitmap,再建立一個canvas,繫結bitmap,最後用picture去繪製。
//獲取Picture物件 Picture picture = wv_capture.capturePicture(); //得到圖片的寬和高(沒有reflect圖片內容) int width = picture.getWidth(); int height = picture.getHeight(); if (width > 0 && height > 0) { //建立點陣圖 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); //繪製(會呼叫native方法,完成圖形繪製) picture.draw(canvas); }
這種方式可以獲取webview中已載入的所有資料影象,也就是長截圖的效果。這種方式在Android 4.4以下是沒有問題的,但是在5.0以上就行不通了。capturePicture()方法在4.4中廢棄掉了,官方建議使用onDrow()方法來獲取webview的bitmap快照。具體實現如下:
//獲取webview縮放率 float scale = wv_capture.getScale(); //得到縮放後webview內容的高度 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);
但是此時在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的快取功能.
webView.setDrawingCacheEnabled(true);
...
Bitmap bitmap = webView.getDrawingCache();
需要注意的是,在上述情況下,這個快取bitmap物件只有一個,因此每次獲取的bitmap指向的是同一塊地址空間的快取物件,如果在使用完bitmap後就立即回收掉這個物件,那麼再次獲取當前view的快取物件時就會得到null。所以要在Activity銷燬時進行回收,所以開啟快取的話會有效能開銷。
第三種方式
比較簡單,通過獲取當前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();
}
}
參考: