首页 > 系统 > Android > 正文

Android WebView实现网页滚动截图

2019-10-22 18:11:58
字体:
来源:转载
供稿:网友

WebView 网页滚动截屏,可对整个网页进行截屏而不是仅当前屏幕哦!

注意若Web页面存在position:fixed; 的话得在调用前设置为 position:absolute; 哦,否则会出现很多次的,请看下面的具体解说吧!!

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();  // 容器内容实际高度  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调用截屏操作

/**  * 屏幕截图  * @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 触发显示了一个原生的 Button按钮, 然后WebView跳转到 csdn 页面,然后点击截屏按钮用来触发网页截屏的。下面的图是我手动截的图,不是上面代码的效果哈,下下面很长的那张才是Java程序的网页截图。

Android,WebView,网页滚动截图,Android滚动截图,WebView截图

测试CSDN的网页完整截图:比较长哦~ 一般截图的功能都用于特殊的页面,如活动页面之类的,不会太长,那样是没有问题的。若是这种滚动到底部自动加载的话可能就会很长很长很长啦·····,自己看着办吧。。

Android,WebView,网页滚动截图,Android滚动截图,WebView截图

但这里有个BUG,顶部固定Banner条每次截屏都有,这个有解决办法,不过得是你自己的网页才有操作权限哦,需要修改JS啦。

当截图JS命令触发前,把顶部悬浮的样式设置为绝对定位,当截屏完成后再改回固定定位即可,没什么难度了。

截屏是需要一些时间的,所以需要预设一个定时器来操作,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);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表