阅读量:0
const { ccclass, property } = cc._decorator; @ccclass export default class ScreenshotCtrl extends cc.Component { @property(cc.Node) ScreenshotNode: cc.Node = null; onScreenshot() { this.captureScreen(this.node) } public getCameraTexture(node: cc.Node): cc.RenderTexture { let camera = node.addComponent(cc.Camera); // 设置你想要的截图内容的 cullingMask camera.cullingMask = 0xffffffff; camera.clearFlags = cc.Camera.ClearFlags.STENCIL | cc.Camera.ClearFlags.DEPTH; camera.depth = 0; camera.rect = cc.rect(0, 0, 1, 1); camera.zoomRatio = Math.min(cc.winSize.height / node.height, cc.winSize.width / node.width) // 新建一个 RenderTexture,并且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。 let texture = new cc.RenderTexture(); texture.initWithSize(node.width, node.height); camera.targetTexture = texture; camera.render(node); //移除相机组件并且销毁相机 node.removeComponent(camera); camera.destroy(); return texture; } /** * 截屏 * @param {*摄像机 cc.Camera类型} camera */ screenShot(node) { const texture: cc.RenderTexture = this.getCameraTexture(node) let canvas = null; //第一步------>给摄像机指定渲染目标 不直接渲染到屏幕上 //第二步----->创建并渲染画布 let width = texture.width; let height = texture.height; if (canvas == null) { //创建canvas canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; } else { //清理画布上指定矩形区域内的像素 canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); } //返回值 ctx 一个 CanvasRenderingContext2D 对象,使用它可以绘制到 Canvas 元素中。 let ctx = canvas.getContext('2d'); //readPixels 方法 从 render texture 读取像素数据 let data = texture.readPixels(); //把从摄像机读取的像素 渲染到canvas画布上去 let rowBytes = width * 4; for (let row = 0; row < height; row++) { let srow = row; let imageData = ctx.createImageData(width, 1);//创建新的空白 ImageData 对象 let start = srow * width * 4; for (let i = 0; i < rowBytes; i++) { imageData.data[i] = data[start + i]; } ctx.putImageData(imageData, 0, height - row - 1);//将图像数据拷贝回画布上 } let a = document.createElement("a"); a.download = "test1.png"; a.href = canvas.toDataURL("image/png"); a.click(); } /** * @description 截图 * @param screenshotNode 截图节点 * @returns 存放截图的本地路径 * 注意1.全屏截图需要添加自适应组件 * 2.带透明的需要存储png格式(会出现亮斑) * 3需要占用内存少,不被透明度营销就存储为.jpg格式 */ public captureScreen(screenshotNode: cc.Node): Promise<string> { return new Promise((resolve, reject) => { const renderTexture = this.getCameraTexture(screenshotNode) const imgData = renderTexture.readPixels() if (CC_JSB) { //CC_JBS标志是原生平台 const shareImgRootPath = `${jsb.fileUtils.getWritablePath()}ShareImg/` const imgFilePath = shareImgRootPath + "_shareImg.jpg" console.log(`imgFilePath:`, imgFilePath); //@ts-ignore const success = jsb.saveImageData(imgData, screenshotNode.width, screenshotNode.height, imgFilePath) //文件写成功之后,返回图片存储的路径 if (success) { resolve(imgFilePath) } else { console.log(`save imgData failed! path:`, imgFilePath); reject(null) } } else { this.screenShot(this.ScreenshotNode) } }) } }