Cocos Creator 2D摄像机 [Lv.2] 截图
Posted VermillionTear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos Creator 2D摄像机 [Lv.2] 截图相关的知识,希望对你有一定的参考价值。
摘要
本文在Cocos Creator 2D摄像机 [Lv.1] 小视图
所完成的工程的基础上进行修改,并增加截图功能。
环境
- Cocos Creator 2.4.4
资源
准备工作
- Cocos Creator 2D摄像机 [Lv.1] 小视图 所完成的工程。
正式开始
对工程做一些修改
资源管理器
拷贝MiniMapDemo
场景,重命名为CaptureScreenDemo
。
拷贝MiniMapController.js
脚本,重命名为CaptureScreenController.js
。
层级管理器
- 将
CaptureScreenController.js
脚本,挂载在CaptureScreenController
节点上。
之后节点相关的设置请参考工程中的设置,文中不再赘述。
如何互动
截图功能需要通过RenderTexture
实现。
将摄像机照到的图像,渲染到RenderTexture
上,然后从RenderTexture
上读取出图像数据。
我们将通过右键点击,来触发截图功能。
通过RenderTexture
+ SpriteFrame
来实现小视图
创建一个sprite
,用来显示小视图,默认的SpriteFrame
删除掉。
在CaptureScreenController.js
中实现功能。
...
let _texture = null // RenderTexture
cc.Class({
...
properties: {
...
smallView: cc.Sprite, // 小视图。
},
onLoad () {
...
_texture = new cc.RenderTexture()
_texture.initWithSize(_canvasWidth, _canvasHeight, cc.gfx.RB_FMT_S8)
this.camera.targetTexture = _texture // 将摄像机的渲染重定向到 RenderTexture 上。
// spriteFrame 的 texture 指定为 RenderTexture ,
// 再把 spriteFrame 添加到 smallView 上,
// 这样摄像机照到的图像就能通过 smallView 显示出来了。
let spriteFrame = new cc.SpriteFrame()
spriteFrame.setTexture(_texture)
this.smallView.spriteFrame = spriteFrame
},
...
});
将节点挂载到脚本对应变量上。
运行起来,看看效果,
小视图怎么这么小,而且还倒过来了。
小视图很小是由于camera.rect
发挥的作用。原先是以整个屏幕作为根本,设置的rect
。现在将targetTexture
定向到了smallView
上,由于smallView
已经设置了需要的大小,所以重置camera.rect
,让其按照默认的位置和尺寸显示就可以了。
显示倒过来的问题,我们可以通过设置smallView
的scaleY = -1
来解决。
同时还有一点,我们要将smallView
的分组设置为brush
。反正不能放在default
分组里,否则小视图又会被摄像机渲染出来。
运行起来,看看效果,
已经能正常显示了。但是又发现个小问题,小视图边框(黄线)的显示不太正常。
这是由于原先通过camera.rect
实现时,小视图边框是通过camera.rect
计算出来的。现在通过smallView
来显示,我们就需要通过其Node
的属性来计算小视图的边框。
在CaptureScreenController.js
中修改calCameraDisplayRect
函数的实现。
calCameraDisplayRect: function () {
let cameraPos = this.smallView.node.getPosition() // 根据 smallView 的位置来计算。
let cameraAnchor = cc.Vec2(this.smallView.node.anchorX, this.smallView.node.anchorX)
let cameraSize = {width: this.smallView.node.width, height: this.smallView.node.height}
// 绘制的矩形以左下角为原点。
return new cc.Rect(cameraPos.x - cameraAnchor.x * cameraSize.width,
cameraPos.y - cameraAnchor.y * cameraSize.height,
cameraSize.width,
cameraSize.height)
},
运行起来,看看效果,
一切都正常了。
截图
在CaptureScreenController.js
中实现功能。
...
cc.Class({
...
onLoad () {
...
// 鼠标释放事件,通过右键点击鼠标截图。
this.node.on(cc.Node.EventType.MOUSE_UP, this.onMouseUp, this)
...
},
...
onMouseUp (event) {
let mouseType = event.getButton()
if (mouseType === cc.Event.EventMouse.BUTTON_RIGHT) { // 鼠标右键释放。
this.captureScreen() // 截图。
}
},
...
captureScreen () {
this.camera.render() // 手动渲染摄像机。
let picData = _texture.readPixels() // 从 RenderTexture 中读取图像数据。
// 图像默认 Y 轴是颠倒的,需要翻转一下 Y 轴。
picData = this.filpYImage(picData, _texture.width, _texture.height)
this.saveFile(picData) // 存储图像。
},
saveFile (picData) {
if (CC_JSB) {
// 存储到可写路径下。
let filePath = jsb.fileUtils.getWritablePath() + 'render_to_sprite_image.png'
// 存储图像。
let success = jsb.saveImageData(picData, _texture.width, _texture.height, filePath)
if (success) {
cc.log("save image data success, file: " + filePath)
}
else {
cc.error("save image data failed!")
}
}
},
// This is a temporary solution
filpYImage (data, width, height) {
// create the data array
let picData = new Uint8Array(width * height * 4) // 每个像素 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
},
})
运行起来,看看效果,
成功生成了截图文件。
划重点
- 通过
RenderTexture
+SpriteFrame
来实现小视图。 Camera.render()
->RenderTexture.readPixels()
->filpYImage()
->jsb.fileUtils.getWritablePath()
->jsb.saveImageData()
。
以上是关于Cocos Creator 2D摄像机 [Lv.2] 截图的主要内容,如果未能解决你的问题,请参考以下文章
Cocos Creator 2D摄像机 [Lv.1] 小视图
Cocos Creator 2D摄像机 [Lv.1] 小视图
Cocos Creator 2D摄像机 [Lv.1] 小视图