前言
Cocos Creator 現在還不是很完善,假如截圖截得是部分節點,所截圖物件會跑到左下角,官方提出的將 renderTexture
新增到場景中去,防止截圖時元素移動,親測這樣雖然截圖時物件不會移動但是截得圖有問題。
一、具體步驟
1、更改被截圖物件的錨點
經過測試,RenderTexture
截圖的時候會將被截圖的物件移到整個場景的左下角,然後根絕設定的 size
,以左下角為座標原點擷取,座標系的錨點是(0,0)。
所以,假如被截圖物件的錨點為(0.5,0.5),則只能擷取右上角的1/4。遂將被截圖物件的錨點設定為(0,0)。
2、新增一個虛假被截圖物件
經過測試,我發現被截圖物件被隱藏後,只要不在本次重新整理介面的時機被啟用,比如在下次重新整理介面的時候啟用,則會恢復到原位(這個啟用操作是必須做的,否則被移動的被截圖物件也不會恢復到原位!)。
基於這個測試結果,我的思路是:代替原被截圖物件,放置一個虛假精靈,在截圖的時候將擷取的圖顯示在這個虛假精靈中,替換原被截圖物件,同時隱藏被截圖物件。這樣就看不到被移動的被截圖物件了。然後在一個合適的時機,再啟用真實被截圖物件,隱藏虛假被截圖物件。
3、正式截圖
① 設定三個物件如下程式碼:
properties: {
// 被截圖物件
cocos: cc.Sprite,
// 顯示截圖的精靈
show: cc.Sprite,
// 被截圖物件的虛假替身
cocosImage: cc.Sprite,
},複製程式碼
需要的注意的是:本例中虛假替身本身是在被截圖的物件的位置的,所以後續不需要設定位置。
② 截圖核心程式碼:
shot: function () {
// 注意,EditBox,VideoPlayer,Webview 等控制元件無法被包含在截圖裡面
// 因為這是 OpenGL 的渲染到紋理的功能,上面提到的控制元件不是由引擎繪製的
if (CC_JSB) {
// 建立 renderTexture
var renderTexture = cc.RenderTexture.create(195, 270);
//實際截圖的程式碼
renderTexture.begin();
this.cocos._sgNode.visit();
renderTexture.end();
// 獲取SpriteFrame
var nowFrame = renderTexture.getSprite().getSpriteFrame();
// 賦值給需要截圖的精靈
this.show.spriteFrame = nowFrame;
// 顯示虛假的代替精靈
this.cocosImage.node.active = true;
this.cocosImage.spriteFrame = nowFrame;
// 翻轉得到的紋理
var action = cc.flipY(true);
this.show.node.runAction(action);
var action1 = cc.flipY(true);
this.cocosImage.node.runAction(action1);
// 隱藏被截圖的物件
this.cocos.node.active = false;
}
},複製程式碼
需要注意的:
i RenderTexture
得到的紋理是上下翻轉的,所以需要相應翻轉回來!假如不坐旋轉就會如下圖:
ii 想要截全屏,只要使用 Canvas
的節點即可,全屏的情況下不需要考慮虛假節點直接擷取即可,記得將初始化 RenderTexture
時,傳入的 size
為全屏的大小。
正常截圖完後的圖如下:
4、顯示原圖
之前也說了,需要在合適時機,啟用被截圖物件,並隱藏虛假被截圖物件,程式碼如下:
this.cocos.node.active = true;
this.cocosImage.node.active = false複製程式碼
二、其他事項
1、如果待截圖的場景中含有 mask
,請使用下面註釋的語句來建立 renderTexture
。
var renderTexture = cc.RenderTexture.create(640,960, cc.Texture2D.PIXEL_FORMAT_RGBA8888, gl.DEPTH24_STENCIL8_OES);複製程式碼
2、把 renderTexture
新增到場景中去,否則截圖的時候,場景中的元素會移動。(確實不移動了,但是截部分節點得圖時有問題,假如哪位童鞋測試沒問題,希望能聯絡我...)
this.node.parent._sgNode.addChild(renderTexture);複製程式碼
3、把 renderTexture
設定為不可見,可以避免截圖成功後,移除 renderTexture
造成的閃爍
renderTexture.setVisible(false);複製程式碼
4、儲存所截的圖,並且列印其地址
// 儲存截圖到本地
renderTexture.saveToFile("demo.png", cc.IMAGE_FORMAT_PNG, true, function () {
});
// 列印本地的地址
cc.log(jsb.fileUtils.getWritablePath());複製程式碼
三、Demo
四、嘿嘿!你懂得!
本文首發於我的個人部落格,希望大家多多支援!