更多内容,请关注公众号:
截图是游戏中一个非常常见的需求,通过摄像机和 RenderTexture 我们可以快速实现一个截图功能
对于截图功能,在 example-cases 中有完整的测试用例,代码示例可参考 07_capture_texture
对于摄像机的介绍,请阅读官方文档:
https://docs.cocos.com/creator/manual/zh/render/camera.html
官方的测试用例中只提供了对屏幕的截图功能,但很多时候,我们只想对某个 node 进行截图
下面提供了两种方法,都可以实现该需求,两种实现方式虽然都是用 Camera 和 RenderTexture ,但还是有些区别,具体的优缺点在哪里,同学们可以自己思考
实现原理在代码中有详细的注释,这里就不再赘述
// 演示 //
// 实现 //
1渲染屏幕,读取 node 区域的像素
captureNode(nodeCapture: cc.Node) {
let nodeCamera = new cc.Node();
nodeCamera.parent = cc.find("Canvas");
let camera = nodeCamera.addComponent(cc.Camera);
let width = nodeCapture.width;
let height = nodeCapture.height;
let texture = new cc.RenderTexture();
texture.initWithSize(cc.visibleRect.width, cc.visibleRect.height, cc.gfx.RB_FMT_S8);
camera.targetTexture = texture;
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext('2d');
camera.render();
// 指定需要读取的区域的像素
let size = nodeCapture.getContentSize();
let pixels = new Uint8Array(size.width * size.height * 4);
let x = texture.width / 2 - nodeCapture.width / 2;
let y = texture.height / 2 - nodeCapture.height / 2;
let w = nodeCapture.width;
let h = nodeCapture.height;
let data = texture.readPixels(pixels, x, y, w, h);
// write the render data
let rowBytes = width * 4;
for (let row = 0; row < height; row++) {
let srow = height - 1 - row;
let imageData = ctx.createImageData(width, 1);
let start = srow * width * 4;
for (let i = 0; i < rowBytes; i++) {
imageData.data[i] = data[start + i];
}
ctx.putImageData(imageData, 0, row);
}
let dataURL = canvas.toDataURL("image/png");
let img = document.createElement("img");
img.src = dataURL;
let texture2D = new cc.Texture2D();
texture2D.initWithElement(img);
let spriteFrame = new cc.SpriteFrame();
spriteFrame.setTexture(texture2D);
let node = new cc.Node();
let sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = spriteFrame;
return node;
}