溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android WebView實(shí)現(xiàn)網(wǎng)頁滾動截圖

發(fā)布時(shí)間:2020-10-17 19:57:19 來源:腳本之家 閱讀:125 作者:神神的蝸牛 欄目:移動開發(fā)

WebView 網(wǎng)頁滾動截屏,可對整個(gè)網(wǎng)頁進(jìn)行截屏而不是僅當(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)容實(shí)際高度
  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ā)顯示了一個(gè)原生的 Button按鈕, 然后WebView跳轉(zhuǎn)到 csdn 頁面,然后點(diǎn)擊截屏按鈕用來觸發(fā)網(wǎng)頁截屏的。下面的圖是我手動截的圖,不是上面代碼的效果哈,下下面很長的那張才是Java程序的網(wǎng)頁截圖。

Android WebView實(shí)現(xiàn)網(wǎng)頁滾動截圖

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

Android WebView實(shí)現(xiàn)網(wǎng)頁滾動截圖

但這里有個(gè)BUG,頂部固定Banner條每次截屏都有,這個(gè)有解決辦法,不過得是你自己的網(wǎng)頁才有操作權(quán)限哦,需要修改JS啦。

當(dāng)截圖JS命令觸發(fā)前,把頂部懸浮的樣式設(shè)置為絕對定位,當(dāng)截屏完成后再改回固定定位即可,沒什么難度了。

截屏是需要一些時(shí)間的,所以需要預(yù)設(shè)一個(gè)定時(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í)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI