WebView 网页滚动截屏,可对整个网页进行截屏而不是仅当前屏幕哦!
注意若Web页面存在position:fixed; 的话得在调用前设置为 position:absolute; 哦,否则会出现很多次的,请看下面的具体解说吧!!
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153private 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调用截屏操作
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31/** * 屏幕截图 * @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程序的网页截图。
测试CSDN的网页完整截图:比较长哦~ 一般截图的功能都用于特殊的页面,如活动页面之类的,不会太长,那样是没有问题的。若是这种滚动到底部自动加载的话可能就会很长很长很长啦·····,自己看着办吧。。
但这里有个BUG,顶部固定Banner条每次截屏都有,这个有解决办法,不过得是你自己的网页才有操作权限哦,需要修改JS啦。
当截图JS命令触发前,把顶部悬浮的样式设置为绝对定位,当截屏完成后再改回固定定位即可,没什么难度了。
截屏是需要一些时间的,所以需要预设一个定时器来操作,JS栗子如下:
JS.Capture 是 WebView 绑定的自定义 Javascript 类对象
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18var 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);
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是认真背包最近收集整理的关于Android WebView实现网页滚动截图的全部内容,更多相关Android内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复