将存储 RGBA 的 Uint8Array 数组保存到 .png 文件
Saving a Uint8Array array storing RGBA to a .png file
我目前正在尝试将 ThreeJS 在特定区域的屏幕截图保存到文件中。
到目前为止,我只尝试将图像显示到新选项卡中,我可以使用它
window.open(renderer.domElement.toDataURL("image/png"));
渲染器是一个 THREE.WebGLRenderer 带有 preserveDrawingBuffer 的对象:true
但是那使用了整个场景,所以我切换到:
var gl = renderer.getContext();
var pixels = new Uint8Array(width * height * 4);
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
window.open("data:image/png;base64," + btoa(String.fromCharCode.apply(null, pixels)));
这样一来,除了一个灰色轮廓的正方形外,什么都没有呈现
在意识到数据不是 png 的正确格式后制定了解决方案。
var gl = renderer.getContext();
var pixels = new Uint8Array(width * height * 4);
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var imageData = ctx.createImageData(width, height);
for(var i = 0; i < imageData.data.length; i+=4) {
imageData.data[i + 0] = pixels[i + 0];
imageData.data[i + 1] = pixels[i + 1];
imageData.data[i + 2] = pixels[i + 2];
imageData.data[i + 3] = pixels[i + 3];
}
ctx.putImageData(imageData,0,0);
window.open(canvas.toDataURL("image/png"));
canvas.remove();
这不是最好的方法,但它奏效了。
如果你想要它的一小部分,而不是调用 gl.readPixels
只需使用 drawImage
的源宽度和高度参数
var gl = renderer.getContext();
var ctx = document.createElement('canvas').getContext("2d");
ctx.canvas.width = width;
ctx.canvas.height = height;
ctx.drawImage(gl.canvas, 0, 0, width, height, 0, 0, width, height);
window.open(ctx.canvas.toDataURL());
有3个版本drawImage
drawImage(image, dstX, dstY)
drawImage(image, dstX, dstY, dstWidth, dstHeight)
drawImage(image, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight)
我目前正在尝试将 ThreeJS 在特定区域的屏幕截图保存到文件中。
到目前为止,我只尝试将图像显示到新选项卡中,我可以使用它
window.open(renderer.domElement.toDataURL("image/png"));
渲染器是一个 THREE.WebGLRenderer 带有 preserveDrawingBuffer 的对象:true
但是那使用了整个场景,所以我切换到:
var gl = renderer.getContext();
var pixels = new Uint8Array(width * height * 4);
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
window.open("data:image/png;base64," + btoa(String.fromCharCode.apply(null, pixels)));
这样一来,除了一个灰色轮廓的正方形外,什么都没有呈现
在意识到数据不是 png 的正确格式后制定了解决方案。
var gl = renderer.getContext();
var pixels = new Uint8Array(width * height * 4);
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
var imageData = ctx.createImageData(width, height);
for(var i = 0; i < imageData.data.length; i+=4) {
imageData.data[i + 0] = pixels[i + 0];
imageData.data[i + 1] = pixels[i + 1];
imageData.data[i + 2] = pixels[i + 2];
imageData.data[i + 3] = pixels[i + 3];
}
ctx.putImageData(imageData,0,0);
window.open(canvas.toDataURL("image/png"));
canvas.remove();
这不是最好的方法,但它奏效了。
如果你想要它的一小部分,而不是调用 gl.readPixels
只需使用 drawImage
var gl = renderer.getContext();
var ctx = document.createElement('canvas').getContext("2d");
ctx.canvas.width = width;
ctx.canvas.height = height;
ctx.drawImage(gl.canvas, 0, 0, width, height, 0, 0, width, height);
window.open(ctx.canvas.toDataURL());
有3个版本drawImage
drawImage(image, dstX, dstY)
drawImage(image, dstX, dstY, dstWidth, dstHeight)
drawImage(image, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight)