webgl渲染模式下分享图片

无聊逛论坛,看到很多朋友问webgl下如何分享图片呢?
用cocos2d-js实现了下
var listener = cc.eventManager.addListener({
event: cc.EventListener.CUSTOM,
eventName: cc.Director.EVENT_AFTER_DRAW ,
callback: function (event) {

			function grab(x, y, width, height) {
				var arrayBuffer = new Uint8Array(width * height * 4);
				cc.game._renderContext.readPixels(x, y, width, height, cc.game._renderContext.RGBA, cc.game._renderContext.UNSIGNED_BYTE, arrayBuffer);
				var clampArray = new Uint8ClampedArray(arrayBuffer, 0, arrayBuffer.length);
				var imageData = new ImageData(clampArray, width, height);
				var tempCanvas = document.createElement('canvas');
				tempCanvas.getContext('2d').putImageData(imageData, 0, 0);
				console.log(tempCanvas.toDataURL());
			}

			//grab(0, 0, cc.game._renderContext.drawingBufferWidth, cc.game._renderContext.drawingBufferHeight);
			grab(20, 350, 100, 100);

			cc.eventManager.removeListener(listener);
			listener = undefined;
		}
	}, this.getRootNode());

要注意一点:一定要在这个事件触发时截图cc.Director.EVENT_AFTER_DRAW ,否则执行代码的时候,整个framebuffer已经被清空了,截取的图片是黑色的。

如果只截取当前屏幕,直接拿document.getElementByID(“GameCanvas”).toDataUrl()
2.分享静态贴图?
texture2d 取到对应的HtmlImageElement
新建一个新的canvas, 然后canvas.getContext(‘2d’).drawImage(HtmlImageElement, x, y, w, h);
canvas…toDataUrl()

这个如果是合图的美术资源,这里需要先根据SpriteFrame计算下贴图的位置,偏移值,旋转。减少复杂度,这类图片不合图。

  1. 分享屏幕局部的图片?
    canvas渲染:拿到GameCanvas,GameCanvas.getContext(“2d”).getImageData(x, y, width, height); x,y为屏幕坐标,宽高是要截取部分的宽高。然后创建一个新的canvas,将ImageData放到新的canvas绘制,这个新的canvas.toDataURL()导出base64

  2. 如果做人物快照,只想分享avatar?
    和webgl截图一样,只不过是渲染到rendertexture上,然后读取像素值,再绘制到canvas上导出base64

native上已经有实现的接口,可以直接用

4赞

this.getRootNode()报错了
我想分享某个区域的截图怎么写呢

this.getRootNode()
这个是绑定事件的node,随便传个node进去都可以

grab(20, 350, 100, 100);
4个参数分别是屏幕x,y,截取的宽高100, 100
自己修改参数



为什么这样写截出来的宽高变了,不是我给入的宽高了

canvas尺寸太小,没画完。
tempCanvas.width = width;
tempCanvas.height = height;
tempCanvas.getContext(‘2d’).putImageData(imageData, 0, 0, 0, 0, tempCanvas.width, tempCanvas.height);
设置下宽高

大小对了,可是还是只有右上角,其他都是黑的

坐标要对齐的,你自己调试下把- -。

把这个tempcanvas appendChild到当前的div下,改改参数调下
顺便确定下rendertexture是不是绘制正确的。

我渲染后的消息怎么一直调用不到。。

1赞

你是用题主说的在EVENT_AFTER_DRAW触发后截图的吗?

为什么我生成的base64图片是倒过来的,为什么

的确是倒过来的

倒过来的问题可以这样解决:

不太建议直接操作像素,尤其截取范围较大时。这个地方在绘制之前把节点的旋转一下,绘制完成之后,再把节点旋转回去。

和你遇到了一样的问题。顶一下。

哦。我找到了!
FAQ · GitBook 浏览器里如何截屏?

最终找到的解决方案:
Cocos Creator教程:截图&切图

cc.director.on(cc.Director.EVENT_AFTER_DRAW, callback.bind(this));

亲测可用!已经能够不黑屏的截屏了!

1赞

多谢老哥提供的 cocos-2d的思路。

引导我成功地找到了 cocos-creator的思路,多谢老哥!!!福寿无量

cc.director.on(cc.Director.EVENT_AFTER_DRAW, callback.bind(this));