Three.js:如何将场景的 2D 快照制作为 JPG 图像?
Posted
技术标签:
【中文标题】Three.js:如何将场景的 2D 快照制作为 JPG 图像?【英文标题】:Three.js: How can I make a 2D SnapShot of a Scene as a JPG Image? 【发布时间】:2014-11-29 09:11:28 【问题描述】:我有一个像下面这样的 three.js 场景:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial(color: 0x00ff00);
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function ()
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
;
render();
是否可以从场景中制作 2D 快照或屏幕截图并将其导出为 JPG 图像?
【问题讨论】:
一些资源可以帮助您:***.com/questions/16431318/… 和 ***.com/questions/15558418/… 初始化 webgl 上下文,将 preserveDrawingBuffer 标志设置为 true 并使用yourCanvas.toDataURL()
。
@LJ_1102 你能发个例子吗?
骗子包括***.com/questions/34847293/…、***.com/questions/15558418/…、***.com/questions/26431862/…
【参考方案1】:
您需要做几件事,将框架保存为 jpg 图像。
首先像这样初始化webgl上下文
renderer = new THREE.WebGLRenderer(
preserveDrawingBuffer: true
);
preserveDrawingBuffer
标志会帮你获取当前帧的base64编码
代码是这样的
var strMime = "image/jpeg";
imgData = renderer.domElement.toDataURL(strMime);
其次,您可能希望使用.jpg
扩展名保存文件,但并非所有浏览器都允许您指定文件名。
我找到的最佳解决方案是this SO thread。
所以我们的脚本将检查浏览器是否允许它会创建一个新的anchor
元素并设置它的download
并单击它(这会将文件保存在指定的文件名中)否则它只会下载文件但用户必须使用 .jpg
扩展名重命名它才能打开它。
Codepen Link
var camera, scene, renderer;
var mesh;
var strDownloadMime = "image/octet-stream";
init();
animate();
function init()
var saveLink = document.createElement('div');
saveLink.style.position = 'absolute';
saveLink.style.top = '10px';
saveLink.style.width = '100%';
saveLink.style.background = '#FFFFFF';
saveLink.style.textAlign = 'center';
saveLink.innerhtml =
'<a href="#" id="saveLink">Save Frame</a>';
document.body.appendChild(saveLink);
document.getElementById("saveLink").addEventListener('click', saveAsImage);
renderer = new THREE.WebGLRenderer(
preserveDrawingBuffer: true
);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxGeometry(200, 200, 200);
var material = new THREE.MeshBasicMaterial(
color: 0x00ff00
);
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
//
window.addEventListener('resize', onWindowResize, false);
function onWindowResize()
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
function animate()
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
function saveAsImage()
var imgData, imgNode;
try
var strMime = "image/jpeg";
imgData = renderer.domElement.toDataURL(strMime);
saveFile(imgData.replace(strMime, strDownloadMime), "test.jpg");
catch (e)
console.log(e);
return;
var saveFile = function (strData, filename)
var link = document.createElement('a');
if (typeof link.download === 'string')
document.body.appendChild(link); //Firefox requires the link to be in the body
link.download = filename;
link.href = strData;
link.click();
document.body.removeChild(link); //remove the link when done
else
location.replace(uri);
html, body
padding:0px;
margin:0px;
canvas
width: 100%;
height: 100%
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
【讨论】:
如果我没听错的话,即使在不支持它的浏览器中,文件也总是保存为 .jpg?您知道如何在不降低浏览器质量的情况下优化导出的图像吗?在桌面上,我使用 imageoptim imageoptim.com,它在 MAC 上效果很好。导出的图像可以在不损失质量的情况下缩小 35%。您知道如何在浏览器中执行此操作吗? @confile: 如果浏览器支持,那么文件将保存在给定的文件名中,如example.jpg
,但如果浏览器不支持它,文件将保存为一些随机自动生成的文件名,如ac2wz43
,没有 .jpg
扩展名,因此用户必须手动将其重命名为带有 .jpg
扩展名的内容才能打开它。您可以在此处检查下载属性的兼容性caniuse.com/#feat=download
@confile:我不确定我们如何在客户端完全优化图像,但您可以搜索其他可能能够做到这一点的 javascript 库。
@shiva: JS Fiddle Link 无法正常工作,请您更正。我需要看一下工作示例。谢谢。
@Shiva - 你的回答很好,非常感谢!希望我能给 +5 而不是 +1!以上是关于Three.js:如何将场景的 2D 快照制作为 JPG 图像?的主要内容,如果未能解决你的问题,请参考以下文章
Three.js/WebGL 和 2D Canvas -- 将 getImageData() 数组传递给 Three.DataTexture()