NoneX BIM Viewer: создание скриншота из canvas
Я использую xBim Toolkit ( http://docs.xbim.net/) для рендеринга 3D-объектов, и было требование создать скриншот текущей сцены при нажатии кнопки. xBim использует canvas для графического представления объекта. Весь проект основан на C#, инструментах.NET и Javascript, так что это набор инструментов, которые можно использовать для решения этой проблемы.
Я уже пробовал использовать библиотеки html2canvas ( https://html2canvas.hertzen.com/) и dom-to-image ( https://github.com/tsayen/dom-to-image), но также пытался использовать холст по умолчанию методы (например, 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);
}
Я хотел бы иметь скриншот только области холста. Это не важно, если это реализовано с использованием кода Javascript или C# (даже с System.Drawing.Graphics, но вырезать только часть экрана)
1 ответ
Если вы используете xBim Toolkit, как описано в вопросе, вы должны знать, что внутренне он использует WebGL для представления объектов. Чтобы сделать снимок экрана при работе WebGl, я нашел один способ (не уверен, что он лучший, но он работает). Вы можете выполнить следующий код Javascript перед загрузкой вашей страницы и программы просмотра xBim:
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();
});