Seeking Advice: Capturing Screenshots with Render Texture in Cocos Creator 3.8.2

Dear Cocos community,

I hope this message finds you well. I’m currently working on a project in Cocos Creator version 3.8.2 and I’m interested in implementing screenshot capture functionality using render texture. Despite my efforts to find relevant resources, I haven’t been able to locate a suitable guide or example for this version.

Could someone kindly point me in the right direction or share some insights on how to achieve this within the context of Cocos Creator 3.8.2? Any code snippets, tips, or documentation references would be greatly appreciated.

Thank you very much for your time and assistance.

FYI.
public static capture(): string {

if (xdSys.platform == xdPlatform.WEB ||

    xdSys.platform == xdPlatform.XQWEB ||

    xdSys.platform == xdPlatform.JSB) {

    let node = xdUIUtil.getUICanvas();

    let renderTex: RenderTexture = new RenderTexture();

    let winSize = xdUIUtil.getViewSize();

    renderTex.initialize({

        width: Math.floor(winSize.width),

        height: Math.floor(winSize.height),

    })

    let camera = node.getComponent(Canvas);

    camera.targetTexture = renderTex;

    director.root.pipeline.render([camera.camera.view]);

    let data = this.copyRenderTex(renderTex);

    camera.targetTexture = null;

    return data;

}

return null;

}

private static copyRenderTex(renderTex: RenderTexture): string {

let arrayBuffer = new ArrayBuffer(renderTex.width * renderTex.height * 4);

let region = new GFXBufferTextureCopy();

region.texOffset.x = 0;

region.texOffset.y = 0;

region.texExtent.width = renderTex.width;

region.texExtent.height = renderTex.height;

director.root.device.copyFramebufferToBuffer(renderTex.window.framebuffer, arrayBuffer, [region]);

if (xdSys.platform == xdPlatform.JSB) {

    let path = xdfile.getWritablePath() + 'capture.jpg';

    this.saveImageData(arrayBuffer, renderTex.width, renderTex.height, path);

    return path;

} else {

    return this.toB64(arrayBuffer);

}

}

private static saveImageData(arrayBuffer: ArrayBuffer, w: number, h: number, path: string) {

let imageU8Data = new Uint8Array(arrayBuffer);

//flip the picture

let picData = new Uint8Array(w * h * 4);

let rowBytes = w * 4;

for (let row = 0; row < h; row++) {

    let srow = h - 1 - row;

    let start = srow * w * 4;

    let reStart = row * w * 4;

    // save the piexls data

    for (let i = 0; i < rowBytes; i++) {

        picData[reStart + i] = imageU8Data[start + i];

    }

}

jsb.saveImageData(picData, w, h, path);

}

private static toB64(arrayBuffer: ArrayBuffer): string {

let canvas = document.createElement('canvas');

let winSize = xdUIUtil.getViewSize();

let width = canvas.width = Math.floor(winSize.width);

let height = canvas.height = Math.floor(winSize.height);

let ctx = canvas.getContext('2d');

let imageU8Data = new Uint8Array(arrayBuffer);

let rowBytes = width * 4;

let rowBytesh = height * 4;

for (let row = 0; row < rowBytesh; row++) {

    let sRow = height - 1 - row;

    let imageData = ctx.createImageData(width, 1);

    let start = sRow * rowBytes;

    for (let i = 0; i < rowBytes; i++) {

        imageData.data[i] = imageU8Data[start + i];

    }

    ctx.putImageData(imageData, 0, row);

}

var base64 = canvas.toDataURL("image/jpeg", 0.7); //compress

return base64;

}

2 Likes

Hey @Tom_k , just wanted to drop by and say a big thank you for your help with my question on the forum. Your response was incredibly helpful and I’m really grateful for your input