# 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(推荐) ```java // 获取 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 ```java // 传入 null 或空字符串会获取页面中第一个 Canvas WebViewScreenshotUtil.getCanvasBase64FromWebView(webView, null, callback); ``` ### 方法3:获取所有 Canvas ```java 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:高级方法(自动回退) ```java // 这个方法会先尝试 JavaScript 方法,失败时自动使用传统截图方法 WebViewScreenshotUtil.captureCanvasAdvanced(webView, "gameCanvas", callback); ``` ### 方法5:传统 WebView 截图转 base64 ```java // 同步方法,直接返回 base64 字符串 String base64 = WebViewScreenshotUtil.captureWebViewToBase64(webView); // 或者指定压缩质量(0-100) String base64 = WebViewScreenshotUtil.captureWebViewToBase64(webView, 80); ``` ## 技术原理 ### JavaScript 方案 通过向 WebView 注入 JavaScript 代码,直接调用 HTML5 Canvas 的 `toDataURL()` 方法: ```javascript // 获取指定 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 截图方法。 ## 最佳实践 1. **等待加载完成**:确保在 WebView 和 Canvas 完全加载后再进行截图 ```java webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // 稍微延迟确保 Canvas 渲染完成 view.postDelayed(() -> { WebViewScreenshotUtil.captureCanvasAdvanced(webView, "gameCanvas", callback); }, 1000); } }); ``` 2. **使用高级方法**:推荐使用 `captureCanvasAdvanced()` 方法,它提供了最好的兼容性 3. **错误处理**:始终实现 `onError` 回调来处理可能的失败情况 4. **内存管理**:如果转换为 Bitmap,记得及时调用 `bitmap.recycle()` 释放内存 ## 兼容性 - **JavaScript 方案**:需要 Android 4.4+ (API 19+) - **传统截图方案**:支持所有 Android 版本 - 自动回退机制确保在所有设备上都能工作 ## 常见问题 1. **Canvas 为空**:确保 Canvas 已经绘制了内容 2. **跨域问题**:如果 Canvas 使用了跨域图片,可能无法导出 3. **硬件加速**:某些情况下可能需要禁用硬件加速 4. **WebGL Canvas**:对于 WebGL Canvas,可能需要特殊处理 ## 性能优化 1. 对于高频截图,考虑使用较低的压缩质量 2. 大尺寸 Canvas 可以考虑先缩放再转换 3. 异步处理,避免阻塞 UI 线程 这个方案为您提供了完整的 WebView Canvas 转 Base64 的解决方案,支持多种场景和自动回退机制。