4.5 KiB
4.5 KiB
WebView Canvas 转 Base64 方案
概述
我为您的 WebViewScreenshotUtil.java 添加了完整的 Canvas 转 Base64 编码的功能。这个方案提供了多种方法来获取 WebView 中的 Canvas 内容。
新增功能
1. 基础功能
bitmapToBase64()- 将 Bitmap 转换为 base64 编码captureWebViewToBase64()- 截取整个 WebView 并转为 base64
2. JavaScript 注入方案(推荐)
getCanvasBase64FromWebView()- 通过 JavaScript 获取指定 Canvas 内容getAllCanvasBase64FromWebView()- 获取页面中所有 Canvas 内容captureCanvasAdvanced()- 高级方法,自动回退机制
使用方法
方法1:获取指定 Canvas(推荐)
// 获取 ID 为 "gameCanvas" 的 Canvas 内容
WebViewScreenshotUtil.getCanvasBase64FromWebView(webView, "gameCanvas",
new WebViewScreenshotUtil.CanvasToBase64Callback() {
@Override
public void onSuccess(String base64Data) {
// 成功获取到 base64 数据
Log.d("Canvas", "Base64 length: " + base64Data.length());
// 在这里处理 base64 数据
}
@Override
public void onError(String error) {
Log.e("Canvas", "获取失败: " + error);
}
});
方法2:获取第一个 Canvas
// 传入 null 或空字符串会获取页面中第一个 Canvas
WebViewScreenshotUtil.getCanvasBase64FromWebView(webView, null, callback);
方法3:获取所有 Canvas
WebViewScreenshotUtil.getAllCanvasBase64FromWebView(webView,
new WebViewScreenshotUtil.CanvasToBase64Callback() {
@Override
public void onSuccess(String jsonResult) {
// jsonResult 是包含所有 Canvas 信息的 JSON 字符串
// 格式:[{"index":0,"id":"canvas1","width":800,"height":600,"dataUrl":"data:image/png;base64,..."}]
}
@Override
public void onError(String error) {
// 处理错误
}
});
方法4:高级方法(自动回退)
// 这个方法会先尝试 JavaScript 方法,失败时自动使用传统截图方法
WebViewScreenshotUtil.captureCanvasAdvanced(webView, "gameCanvas", callback);
方法5:传统 WebView 截图转 base64
// 同步方法,直接返回 base64 字符串
String base64 = WebViewScreenshotUtil.captureWebViewToBase64(webView);
// 或者指定压缩质量(0-100)
String base64 = WebViewScreenshotUtil.captureWebViewToBase64(webView, 80);
技术原理
JavaScript 方案
通过向 WebView 注入 JavaScript 代码,直接调用 HTML5 Canvas 的 toDataURL() 方法:
// 获取指定 Canvas
var canvas = document.getElementById('canvasId');
var dataUrl = canvas.toDataURL('image/png');
// 获取第一个 Canvas
var canvases = document.getElementsByTagName('canvas');
var dataUrl = canvases[0].toDataURL('image/png');
传统截图方案
如果 JavaScript 方案失败,会自动回退到传统的 Android View 截图方法。
最佳实践
- 等待加载完成:确保在 WebView 和 Canvas 完全加载后再进行截图
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
// 稍微延迟确保 Canvas 渲染完成
view.postDelayed(() -> {
WebViewScreenshotUtil.captureCanvasAdvanced(webView, "gameCanvas", callback);
}, 1000);
}
});
-
使用高级方法:推荐使用
captureCanvasAdvanced()方法,它提供了最好的兼容性 -
错误处理:始终实现
onError回调来处理可能的失败情况 -
内存管理:如果转换为 Bitmap,记得及时调用
bitmap.recycle()释放内存
兼容性
- JavaScript 方案:需要 Android 4.4+ (API 19+)
- 传统截图方案:支持所有 Android 版本
- 自动回退机制确保在所有设备上都能工作
常见问题
- Canvas 为空:确保 Canvas 已经绘制了内容
- 跨域问题:如果 Canvas 使用了跨域图片,可能无法导出
- 硬件加速:某些情况下可能需要禁用硬件加速
- WebGL Canvas:对于 WebGL Canvas,可能需要特殊处理
性能优化
- 对于高频截图,考虑使用较低的压缩质量
- 大尺寸 Canvas 可以考虑先缩放再转换
- 异步处理,避免阻塞 UI 线程
这个方案为您提供了完整的 WebView Canvas 转 Base64 的解决方案,支持多种场景和自动回退机制。