Android WebView實現(xiàn)網(wǎng)頁滾動截圖
WebView 網(wǎng)頁滾動截屏,可對整個網(wǎng)頁進行截屏而不是僅當(dāng)前屏幕哦!
注意若Web頁面存在position:fixed; 的話得在調(diào)用前設(shè)置為 position:absolute; 哦,否則會出現(xiàn)很多次的,請看下面的具體解說吧??!
private static Bitmap getViewBitmapWithoutBottom(View v) {
if (null == v) {
return null;
}
v.setDrawingCacheEnabled(true);
v.buildDrawingCache();
if (Build.VERSION.SDK_INT >= 11) {
v.measure(View.MeasureSpec.makeMeasureSpec(v.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(v.getHeight(), View.MeasureSpec.EXACTLY));
v.layout((int) v.getX(), (int) v.getY(), (int) v.getX() + v.getMeasuredWidth(), (int) v.getY() + v.getMeasuredHeight());
} else {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
}
Bitmap bp = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight() - v.getPaddingBottom());
v.setDrawingCacheEnabled(false);
v.destroyDrawingCache();
return bp;
}
public static Bitmap getViewBitmap(View v) {
if (null == v) {
return null;
}
v.setDrawingCacheEnabled(true);
v.buildDrawingCache();
if (Build.VERSION.SDK_INT >= 11) {
v.measure(View.MeasureSpec.makeMeasureSpec(v.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(v.getHeight(), View.MeasureSpec.EXACTLY));
v.layout((int) v.getX(), (int) v.getY(), (int) v.getX() + v.getMeasuredWidth(), (int) v.getY() + v.getMeasuredHeight());
} else {
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
}
Bitmap b = Bitmap.createBitmap(v.getDrawingCache(), 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.setDrawingCacheEnabled(false);
v.destroyDrawingCache();
return b;
}
/**
* 獲取 WebView 視圖截圖
* @param context
* @param view
* @return
*/
public static Bitmap getWebViewBitmap(Context context, WebView view) {
if (null == view) return null;
view.scrollTo(0, 0);
view.buildDrawingCache(true);
view.setDrawingCacheEnabled(true);
view.setVerticalScrollBarEnabled(false);
Bitmap b = getViewBitmapWithoutBottom(view);
// 可見高度
int vh = view.getHeight();
// 容器內(nèi)容實際高度
int th = (int)(view.getContentHeight()*view.getScale());
Bitmap temp = null;
if (th > vh) {
int w = getScreenWidth(context);
int absVh = vh - view.getPaddingTop() - view.getPaddingBottom();
do {
int restHeight = th - vh;
if (restHeight <= absVh) {
view.scrollBy(0, restHeight);
vh += restHeight;
temp = getViewBitmap(view);
} else {
view.scrollBy(0, absVh);
vh += absVh;
temp = getViewBitmapWithoutBottom(view);
}
b = mergeBitmap(vh, w, temp, 0, view.getScrollY(), b, 0, 0);
} while (vh < th);
}
// 回滾到頂部
view.scrollTo(0, 0);
view.setVerticalScrollBarEnabled(true);
view.setDrawingCacheEnabled(false);
view.destroyDrawingCache();
return b;
}
/**
* 拼接圖片
* @param newImageH
* @param newImageW
* @param background
* @param backX
* @param backY
* @param foreground
* @param foreX
* @param foreY
* @return
*/
private static Bitmap mergeBitmap(int newImageH, int newImageW, Bitmap background, float backX, float backY, Bitmap foreground, float foreX, float foreY) {
if (null == background || null == foreground) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(newImageW, newImageH, Bitmap.Config.RGB_565);
Canvas cv = new Canvas(bitmap);
cv.drawBitmap(background, backX, backY, null);
cv.drawBitmap(foreground, foreX, foreY, null);
cv.save(Canvas.ALL_SAVE_FLAG);
cv.restore();
return bitmap;
}
/**
* get the width of screen
*/
public static int getScreenWidth(Context ctx) {
int w = 0;
if (Build.VERSION.SDK_INT > 13) {
Point p = new Point();
((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(p);
w = p.x;
} else {
w = ((WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
}
return w;
}
/**
* 保存圖片
* @param context
* @param bitmap
* @param file
* @param quality
* @return
*/
public static boolean save(Context context, Bitmap bitmap, File file, int quality) {
if (bitmap == null) return false;
// 獲得后綴格式
String abs = file.getAbsolutePath();
String suffix = abs.substring(abs.lastIndexOf(".")+1).toLowerCase();
Bitmap.CompressFormat format;
if ("jpg".equals(suffix) || "jpeg".equals(suffix)) {
format = Bitmap.CompressFormat.JPEG;
} else {
format = Bitmap.CompressFormat.PNG;
quality = 100;
}
if (file.exists() && ! file.delete()) return false;
try {
FileOutputStream stream = new FileOutputStream(file);
bitmap.compress(format, quality, stream);
stream.flush();
stream.close();
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
return true;
} catch (Exception e) {
return false;
}
}
JS調(diào)用截屏操作
/**
* 屏幕截圖
* @param name
* @param isRecover
*/
@JavascriptInterface
public String Capture(String name, boolean isRecover) {
File dir = new File(Config.PUBLIC_PICTURES_PATH);
LogUtil.i("capture", dir.getAbsolutePath());
if (! dir.exists() && ! dir.mkdirs()) return null;
final File file = new File(dir, name);
String path = file.getAbsolutePath();
if (file.exists() && ! isRecover) return path;
body.post(new Runnable() {
@Override
public void run() {
Bitmap bitmap = CaptureUtil.getWebViewBitmap(activity, body);
if (null != bitmap) ImageUtil.save(activity, bitmap, file, 100);
}
});
return path;
}
@JavascriptInterface
public String Capture(String name) {
return Capture(name, true);
}
@JavascriptInterface
public String Capture() {
String name = String.valueOf(System.currentTimeMillis()) + ".png";
return Capture(name);
}
示例圖:我先通過 JS 觸發(fā)顯示了一個原生的 Button按鈕, 然后WebView跳轉(zhuǎn)到 csdn 頁面,然后點擊截屏按鈕用來觸發(fā)網(wǎng)頁截屏的。下面的圖是我手動截的圖,不是上面代碼的效果哈,下下面很長的那張才是Java程序的網(wǎng)頁截圖。

測試CSDN的網(wǎng)頁完整截圖:比較長哦~ 一般截圖的功能都用于特殊的頁面,如活動頁面之類的,不會太長,那樣是沒有問題的。若是這種滾動到底部自動加載的話可能就會很長很長很長啦·····,自己看著辦吧。。

但這里有個BUG,頂部固定Banner條每次截屏都有,這個有解決辦法,不過得是你自己的網(wǎng)頁才有操作權(quán)限哦,需要修改JS啦。
當(dāng)截圖JS命令觸發(fā)前,把頂部懸浮的樣式設(shè)置為絕對定位,當(dāng)截屏完成后再改回固定定位即可,沒什么難度了。
截屏是需要一些時間的,所以需要預(yù)設(shè)一個定時器來操作,JS栗子如下:
JS.Capture 是 WebView 綁定的自定義 Javascript 類對象
var file = '';
var $header = $("#layout-header");
$header.css({ position: "absolute" });
setTimeout(function(){
if (typeof name == "function" || typeof name == "undefined") {
file = JS.Capture();
} else {
file = JS.Capture(name, isRecover);
}
}, 500);
setTimeout(function(){
JS.Toast("截圖已保存", "fast");
JS.Toast(file.replace("storage/emulated/0/", ""));
$header.css({ position: "fixed" });
if ($.isFunction(callback)) {
callback(file);
}
}, 1500);
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android WebView打開網(wǎng)頁一片空白的解決方法
- Android開發(fā)筆記之如何正確獲取WebView的網(wǎng)頁Title
- 詳解android 用webview加載網(wǎng)頁(https和http)
- Android開發(fā)中使用WebView控件瀏覽網(wǎng)頁的方法詳解
- Android編程實現(xiàn)webview將網(wǎng)頁打包成apk的方法
- Android中替換WebView加載網(wǎng)頁失敗時的頁面
- Android中Webview打開網(wǎng)頁的同時發(fā)送HTTP頭信息方法
- Android webView如何輸出自定義網(wǎng)頁
相關(guān)文章
Android 圖片特效如何實現(xiàn)及總結(jié)
這篇文章主要介紹了Android 圖形特效如何實現(xiàn)及總結(jié)的相關(guān)資料,這里對Android圖像特效的實現(xiàn)比如:旋轉(zhuǎn),放大,縮小,傾斜等,需要的朋友可以參考下2016-12-12
解析Android中string-array數(shù)據(jù)源的簡單使用
本篇文章是對Android中string-array數(shù)據(jù)源的使用進行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android Activity切換(跳轉(zhuǎn))時出現(xiàn)黑屏的解決方法 分享
Android Activity切換(跳轉(zhuǎn))時出現(xiàn)黑屏的解決方法 分享,需要的朋友可以參考一下2013-06-06
Android如何使用RecyclerView打造首頁輪播圖
這篇文章主要為大家詳細(xì)介紹了Android如何使用RecyclerView打造首頁輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Android應(yīng)用中拍照后獲取照片路徑并上傳的實例分享
這篇文章主要介紹了Android應(yīng)用中拍照后獲取照片路徑并上傳的實例分享,文中使用MultipartEntityBuilder制作了一個簡單的上傳工具,需要的朋友可以參考下2016-03-03
詳解Android應(yīng)用開發(fā)中Scroller類的屏幕滑動功能運用
這篇文章主要介紹了詳解Android應(yīng)用開發(fā)中Scroller類的屏幕滑動功能運用,文中包括各種觸摸滑屏手勢相關(guān)方法的示例,需要的朋友可以參考下2016-02-02
android圖像繪制(六)獲取本地圖片或拍照圖片等圖片資源
從SD卡中獲取圖片資源,或者拍一張新的圖片,然后再進行處理(直接處理返回圖片/獲得圖片的地址再處理)接下來為您詳細(xì)介紹,感興趣的朋友可以了解下2013-01-01

