xBIM 查看器:从 canvas 创建屏幕截图

xBIM Viewer: Create a screenshot from canvas

我正在使用 xBim 工具包 (http://docs.xbim.net/) 进行 3D 对象渲染,需要在单击按钮时创建当前场景的屏幕截图。 xBim 使用 canvas 作为对象的图形表示。 整个项目是基于C#、.NET工具和Javascript,所以这是可以用来解决这个问题的工具范围。

我已经尝试使用 html2canvas (https://html2canvas.hertzen.com/) and dom-to-image (https://github.com/tsayen/dom-to-image) 库,但也尝试使用默认的 canvas 方法(如 myCanvas.toDataUrl() 或 myCanvas.toBlob()). 它们都只产生一个黑色或白色背景的空图像,但没有保存 xBim 对象。

我获得任何有用屏幕截图的唯一方法是使用 System.Drawing.Graphics 然后创建整个屏幕的屏幕截图(出于多种原因,这不是最佳实现方式)。

public static void MakeScreenshot()
{
    var x = Math.Abs(WebBrowser.MousePosition.X);
    var y = Math.Abs(WebBrowser.MousePosition.Y);
    var bounds = Screen.FromPoint(new Point(x, y)).Bounds;

    Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);

    Graphics graphics = Graphics.FromImage(bitmap as System.Drawing.Image);
            graphics.CopyFromScreen(25, 25, 25, 25, bitmap.Size);

    string screenshotFilePath = Path.Combine(DirectoryPath, "Screenshot.jpg");

    bitmap.Save(screenshotFilePath, ImageFormat.Jpeg);
}

我只想要 canvas 区域的屏幕截图。 它是否通过使用 Javascript 或 C# 代码实现并不重要(即使使用 System.Drawing.Graphics,但只剪切部分屏幕)

如果您按照问题所述使用 xBim 工具包,则需要知道它在内部使用 WebGL 进行对象表示。 为了在 WebGl 为 运行 时截屏,我找到了一种方法(不确定它是否是最好的,但它有效)。 您可以在加载页面和 xBim 查看器之前执行以下 Javascript 代码:

HTMLCanvasElement.prototype.getContext = function (origFn) {
        return function (type, attributes) {
            if (type === 'webgl') {
                attributes = Object.assign({}, attributes, {
                    preserveDrawingBuffer: true,
                });
            }
            return origFn.call(this, type, attributes);
        };
    }(HTMLCanvasElement.prototype.getContext);

它应该保留绘图缓冲区并使您能够以一些已知的方式获取屏幕截图,例如使用 dom-to-image 库:

domtoimage.toJpeg(document.getElementById('canvas'), { quality: 0.95 })
            .then(function (dataUrl) {
                var link = document.createElement('a');
                link.download = 'Screenshot.jpeg';
                link.href = dataUrl;
                link.click();
            });