Creator2.1.0 如何在 iOS 平台给指定节点截屏?

我创建了 samples 的工程, 对着里面的 capture screen 来实现, 但是发现了几个问题:

  1. RenderTexture 的 initWithSize 的第三个参数是什么? 项目是 ts, cc.game._renderContext 是报错的;
  2. 如果不传第三个参数/或者照着 sample 的传入, cc.game._renderContext.STENCIL_INDEX8 执行之后会报错;

[ERROR] (/Applications/CocosCreator.app/Contents/Resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_opengl_manual.cpp, 1888): glReadPixels((GLint)arg0 , (GLint)arg1 , (GLsizei)arg2 , (GLsizei)arg3 , (GLenum)arg4 , (GLenum)arg5 , (GLvoid*)arg6 ); GL error 0x506: GL_INVALID_FRAMEBUFFER_OPERATION
[ERROR] Failed to invoke JSB_glReadPixels, location: /Applications/CocosCreator.app/Contents/Resources/cocos2d-x/cocos/scripting/js-bindings/manual/jsb_opengl_manual.cpp:1892
JS: [WARN]: Unknown TEXTURE_FMT: 32
JS: save image data success, file: /var/mobile/Containers/Data/Application/3F38FBA7-4698-4ED8-BD79-31D59FD39AD2/Documents/tmp.png

运行环境:
Creator 2.1.0
iOS 12.1 iPhone7

截屏代码:
`
let parent = cc.director.getScene();
let filePath = jsb.fileUtils.getWritablePath() + “tmp.png”;

  // init
  let texture = new cc.RenderTexture();
  texture.initWithSize(
    parent.getContentSize().width,
    parent.getContentSize().height,
    cc.game._renderContext.STENCIL_INDEX8
  );
  App.getInstance().camera.targetTexture = texture;

  // flip y
  let data = texture.readPixels();
  let width = texture.width;
  let height = texture.height;
  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;
    for (let i = 0; i < rowBytes; i++) {
      picData[reStart + i] = data[start + i];
    }
  }

  // copy sprite
  let texture2D = new cc.Texture2D();
  texture2D.initWithData(picData, 32, width, height);

  let spriteFrame = new cc.SpriteFrame();
  spriteFrame.setTexture(texture2D);

  let node = new cc.Node();
  let sprite = node.addComponent(cc.Sprite);
  sprite.spriteFrame = spriteFrame;

  node.zIndex = cc.macro.MAX_ZINDEX;
  node.parent = parent;
  node.x = width / 2.0;
  node.y = height / 2.0;

  // save
  let success = jsb.saveImageData(picData, width, height, filePath);
  if (success) {
    cc.log("save image data success, file: " + filePath);
  } else {
    cc.error("save image data failed!");
  }

  node.runAction(cc.sequence(cc.delayTime(0), cc.callFunc(() => node.destroy())));

`

https://forum.cocos.com/t/cocos2-02-android/67744/27

自己回复, 可以参考这个帖子, 里面截屏的代码和 sample 是不同的. 反转的问题就不纠结了, 1.x 就存在了, 解决方式很多.

解决.

下面是参考 2 楼的链接, 修改之后的解决方案(我不明白为什么官方为什么不改 sample, 它甚至和文档同样重要):
`public static captureScreen(parent: cc.Node, filePath: string) {
let node = new cc.Node();
node.parent = parent;
node.width = parent.getContentSize().width;
node.height = parent.getContentSize().height;
let camera = node.addComponent(cc.Camera);

// 新建一个 RenderTexture,并且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。
let texture = new cc.RenderTexture();
texture.initWithSize(node.width, node.height);
camera.targetTexture = texture;

// 渲染一次摄像机,即更新一次内容到 RenderTexture 中
parent.scaleY = -1;
camera.render(node.parent);
parent.scaleY = 1;

// 这样我们就能从 RenderTexture 中获取到数据了
let data = texture.readPixels();
let width = texture.width;
let height = texture.height;
let fullPath = filePath;
if (jsb.fileUtils.isFileExist(fullPath)) {
  jsb.fileUtils.removeFile(fullPath);
}

return jsb.saveImageData(data, width, height, fullPath);

}`

2赞