1. 程式人生 > >Webview截圖三種方式

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();
        }

    }

參考: