WebView 如何实现长截图

当webview内容大于一个屏幕时,需要截取在整个webview的内容。

HarmonyOS
2024-05-20 20:47:37
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
sslijun

可以通过canvas组件实现,代码如下:

// TODO: 按下截图后增加提示,禁用用户输入 
const lastH5XOffset = this.curH5XOffset 
const lastH5YOffset = this.curH5YOffset; 
  
try { 
  // 清空Canvas 
  this.canvasCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); 
  // 滚动至页面起始位置 
  this.webviewController.scrollTo(0, 0); 
  // 获取H5、Web宽高 
  const getRectScript: string = 'h5Width=docEl.offsetWidth;h5Height=docEl.offsetHeight;webWidth=docEl.clientWidth;webHeight=docEl.clientHeight;JSProxy.getH5Rect(h5Width,h5Height);JSProxy.getWebRect(webWidth,webHeight);'; 
  const runJavaScriptRes = await this.webviewController.runJavaScriptExt(getRectScript); 
  console.info(`Invoke webviewController.runJavaScript succeed! runJavaScriptRes, ${JSON.stringify(runJavaScriptRes)}, h5Height: ${this.h5Height}, h5Width: ${this.h5Width}, webWidth: ${this.webWidth}, webHeight: ${this.webHeight}`); 
  // 截图会获取最近一帧的绘制内容。如果在组件触发更新的同时调用截图,更新的渲染内容不会被截取到,截图会返回上一帧的绘制内容 
  // Web组件滚动界面更新有延时,需要延时执行组件截图 
  await sleep(100); 
} catch (err) { 
  console.error(`Invoke webviewController.getPageHeight/runJavaScript failed! err: ${JSON.stringify(err)}`); 
} 
// 开始滚动截图 
// 计算滚动次数 
const scrollTimes = Math.ceil(this.h5Height / this.webHeight); 
console.info(`Invoke scrollTimes: ${scrollTimes}`); 
// 绘制到离屏Canvas Y轴的偏移量 
let curDrawCanvasYOffset: number = 0; 
// 绘制比例 
const drawScale: number = this.canvasHeight / this.h5Height; 
  
try { 
  for (let i = 0; i < scrollTimes; i++) { 
    // 滚动页面 
    this.webviewController.scrollBy(0, this.webHeight); 
  
    // 获取当前Web组件截图PixelMap 
    const curWebSnapShot: image.PixelMap = await componentSnapshot.get(this.webId); 
  
    // 绘制到离屏Canvas上 
    if (this.h5Height % this.webHeight !== 0 && i === scrollTimes - 1) { 
      // 裁切源图像时距离源图像左上角的y坐标值,单位:px 
                  const cropY = this.webHeight - (this.h5Height - (this.webHeight * (scrollTimes - 1))); 
      // 裁切源图像时需要裁切的宽度,单位:px 
      const cropWidth = vp2px(this.webWidth); 
      // 裁切源图像时需要裁切的高度,单位:px 
      const cropHeight = this.webHeight - cropY; 
      // 多余部分进行裁剪绘制到离屏Canvas 
      this.offCanvasCtx.drawImage(curWebSnapShot, 0, vp2px(cropY), cropWidth, vp2px(cropHeight), 0, curDrawCanvasYOffset * drawScale, this.canvasWidth, cropHeight * drawScale); 
  
  
      // 将离屏Canvas转换为ImageBItmap后绘制到Canvas上 
      const h5SnapShot: ImageBitmap = this.offCanvasCtx.transferToImageBitmap(); 
      this.canvasCtx.transferFromImageBitmap(h5SnapShot); 
      // 滚动截图结束,显示截图结果 
      this.isSnapshotShow = Visibility.Visible; 
      // 滚动到截图之前的滚动偏移量 
      this.webviewController.scrollTo(lastH5XOffset, lastH5YOffset); 
      break; 
    } 
    // 绘制到离屏Canvas 
    this.offCanvasCtx.drawImage(curWebSnapShot, 0, curDrawCanvasYOffset * drawScale, this.canvasWidth, this.webHeight * drawScale); 
    // 修改Y轴偏移量 
    curDrawCanvasYOffset += this.webHeight; 
  } 
} catch (err) { 
  console.error(`Invoke componentSnashot.get failed! err: ${JSON.stringify(err)}`); 
}
分享
微博
QQ
微信
回复
2024-05-21 16:27:01
相关问题
如何对某个组件实现局部截图
363浏览 • 1回复 待解决
鸿蒙截图功能实现的问题
10372浏览 • 1回复 待解决
http连接的实现方式
482浏览 • 1回复 待解决
如何实现http连接,有人知道吗?
1682浏览 • 1回复 待解决
除了轮询和连接如何实现实时通许?
2109浏览 • 1回复 待解决
webview如何实现charles抓包
1148浏览 • 1回复 待解决
webview如何实现网络请求拦截功能
2242浏览 • 1回复 待解决
如何申请多个时任务
1993浏览 • 1回复 待解决
如何获取窗口截图并显示在Image中?
414浏览 • 1回复 待解决
HarmonyOS WebView实现同层渲染资料
368浏览 • 1回复 待解决