Android WebView实现网页滚动截图

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程序的网页截图。

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

但这里有个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);

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

以上是 Android WebView实现网页滚动截图 的全部内容, 来源链接: utcz.com/p/240403.html

回到顶部