You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Autodesk Forge Viewer getScreenshot方法截图宽高比控制问题求助

问题:Autodesk Forge Viewer getScreenshot 无法按指定宽高比生成截图

问题描述:

我尝试用Autodesk Forge Viewer的getScreenshot方法,指定明确的宽高来生成截图,当前代码是:

this.viewer.getScreenShot( this.width, this.height, img => this.createPDF(img));

当我把高度设为画布完整高度时,能计算对应宽度适配1:2这类比例;但想要计算高度匹配16:9比例时,不管设置的this.height是多少,截图都会用画布的完整高度,宽度自动调整成16:9。我不确定是操作有误、漏了设置,还是这是Viewer的固有特性,导致没法基于当前画布生成16:9的截图。目前我已经能基于比例和clientToWorld坐标渲染出对应帧,但截图始终会扩展为完整画布高度,求解决方案。


解决方案:

首先得明确:这其实是Forge Viewer getScreenshot方法的固有特性——它会优先保证场景内容的原始比例不被拉伸,所以当你传入的宽高比例和当前Viewer视口比例不一致时,它会自动调整你传入的参数,优先匹配场景的原始比例,这就导致了你遇到的问题。下面提供两种可行的解决思路:

1. 手动裁剪截图(推荐,不影响用户界面)

既然getScreenshot返回的是完整画布的图像,我们可以手动创建一个canvas,按照目标比例裁剪出需要的区域,再把裁剪后的图像传入你的createPDF方法。示例代码如下:

this.viewer.getScreenShot(this.viewer.container.clientWidth, this.viewer.container.clientHeight, (img) => {
  // 定义目标宽高比,比如16:9
  const targetRatio = 16 / 9;
  let cropWidth, cropHeight, startX, startY;

  // 计算裁剪区域(以图像中心为基准,保证内容居中)
  if (img.width / img.height > targetRatio) {
    // 原图宽高比大于目标比例,裁剪左右两侧
    cropHeight = img.height;
    cropWidth = cropHeight * targetRatio;
    startX = (img.width - cropWidth) / 2;
    startY = 0;
  } else {
    // 原图宽高比小于目标比例,裁剪上下两侧
    cropWidth = img.width;
    cropHeight = cropWidth / targetRatio;
    startY = (img.height - cropHeight) / 2;
    startX = 0;
  }

  // 创建用于裁剪的canvas
  const cropCanvas = document.createElement('canvas');
  cropCanvas.width = cropWidth;
  cropCanvas.height = cropHeight;
  const ctx = cropCanvas.getContext('2d');
  // 绘制裁剪区域到新canvas
  ctx.drawImage(img, startX, startY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);

  // 将裁剪后的canvas转为图像,传入createPDF
  const croppedImg = new Image();
  croppedImg.src = cropCanvas.toDataURL('image/png');
  croppedImg.onload = () => {
    this.createPDF(croppedImg);
  };
});

2. 临时调整Viewer视口(适合需要精确渲染比例的场景)

如果你希望截图就是Viewer渲染时的精确比例(而非事后裁剪),可以临时修改Viewer容器的宽高为目标比例,刷新渲染后再截图,最后恢复容器原始尺寸:

// 保存容器原始尺寸
const originalWidth = this.viewer.container.clientWidth;
const originalHeight = this.viewer.container.clientHeight;

// 目标宽高比16:9,这里以原始宽度为基准计算对应高度
const targetHeight = originalWidth / (16/9);

// 修改容器样式为目标尺寸
this.viewer.container.style.width = `${originalWidth}px`;
this.viewer.container.style.height = `${targetHeight}px`;

// 刷新Viewer渲染,让场景适配新的视口
this.viewer.resize();

// 延迟截图,确保Viewer完成渲染(时间可根据实际情况调整)
setTimeout(() => {
  this.viewer.getScreenShot(originalWidth, targetHeight, (img) => {
    this.createPDF(img);
    // 恢复容器原始尺寸并刷新
    this.viewer.container.style.width = `${originalWidth}px`;
    this.viewer.container.style.height = `${originalHeight}px`;
    this.viewer.resize();
  });
}, 500);

注意事项:

  • 临时调整视口的方法需要给Viewer足够的渲染时间,建议用viewer.waitForLoadDone()替代setTimeout,能更精准地捕获渲染完成的时机。
  • 手动裁剪的方法不会改变用户看到的界面,更适合大多数场景;而临时调整视口的方法会让界面短暂变化,需要根据你的需求选择。

内容的提问来源于stack exchange,提问作者JuliTrusalin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:14:10