一、Egret截图实现
白鹭的截图实现很简单,在官网教学实例里面就有较详细的例子,下面我只贴出关键的代码;
//RenderTexture 是动态纹理类,他实现了将显示对象及其子对象绘制成为一个纹理的功能
/** drawToTexture * 将指定显示对象绘制为一个纹理 * @param displayObject {egret.DisplayObject} 需要绘制的显示对象 * @param clipBounds {egret.Rectangle} 绘制矩形区域 * @param scale {number} 缩放比例 * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ var rt:egret.RenderTexture = new egret.RenderTexture; rt.drawToTexture( param1, param2, param3);
RenderTexture是继承自egret.Texture;上面代码绘制成一个纹理后,可以直接给 egret.bitmap的 texture的属性附上值;
let _bmpSnap: egret.Bitmap = new egret.Bitmap;
_bmpSnap.texture = rt;
这时候就可以把 _bmpSnap 添加到显示的界面上就行了
二、Cocos 截图实现
先看一下界面如何摆放
首先在界面上放置一个摄像机;如图screenshot;我这里因为游戏需要,为了不影响mianCamera的其他功能,就重新创建了一个,
接下来,把screenshot挂载到脚本声明的变量上面;
图上还缺少一个放截图的sprite组件的节点
同理我们挂载到变量 testSprite上面;
接下来就是实现的代码了;
const { ccclass, property } = cc._decorator; export default class ScreenShot extends cc.Component { private static instance: ScreenShot; @property(cc.Camera) public testCamera: cc.Camera = null; @property(cc.Sprite) public testSprite: cc.Sprite = null; public static getInstance(): ScreenShot { if (ScreenShot.instance == null) { ScreenShot.instance = new ScreenShot(); } return ScreenShot.instance; } public _canvas: any = null; public texture: cc.RenderTexture; private _ number = 0; private _height: number = 0; start() { } onOpen() { this.screenshotsInti();//首先进行初始化 this.scheduleOnce(() => { //spriteFrame可以用于替换精灵中的spriteFrame属性来显示截图 this.screenshots((spriteFrame) => { this.testSprite.spriteFrame = spriteFrame }); }, 0) } screenshotsInti() {//截图初始化 let texture = new cc.RenderTexture(); let gl = cc.game["_renderContext"]; texture.initWithSize(cc.visibleRect.width, cc.visibleRect.height, gl.STENCIL_INDEX8); this.testCamera.getComponent(cc.Camera).targetTexture = texture; this.texture = texture; } screenshots(callback) { //截图函数 let picData = this.initImage(); let spriteFrame = this.showSprite(picData); if (callback) callback(spriteFrame); } initImage() { let data = this.texture.readPixels(); this._width = this.texture.width; this._height = this.texture.height; let picData = this.filpYImage(data, this._width, this._height); return picData; } showSprite(picData) { let texture = new cc.Texture2D(); console.log('canvas', this._width, this._height); //cc.Texture2D.RGBA8888是一个cc.Texture2D中的枚举,可以自行查阅官网API texture.initWithData(picData, cc.Texture2D["RGBA8888"], this._width, this._height); let spriteFrame = new cc.SpriteFrame(); spriteFrame.setTexture(texture); return spriteFrame; } filpYImage(data, width, height) { // create the data array let picData = new Uint8Array(width * height * 4); let rowBytes = width * 4; for (let row = 0; row < height; row++) { let srow = height - 1 - row; let start = srow * width * 4; let reStart = row * width * 4; // save the piexls data for (let i = 0; i < rowBytes; i++) { picData[reStart + i] = data[start + i]; } } return picData; } }
调用 onOpen实现截图;首先调用screenshotsInti()初始化创建一个 RenderTexture,应该是和白鹭的原理一样,都是创建一个动态的纹理集;
this.testCamera.getComponent(cc.Camera).targetTexture = texture;
这一步其实拿到摄像机显示的画面,处理成纹理集;
(但是这一步有点看不懂,前后是不是颠倒了????写法是这样的,大家研究一下)
scheduleOnce这里放个计时器,按需求写,可以不写。
最后直接给 this.testSprite.spriteFrame 赋值就可以了。