creator3.3 怎样实现截取屏幕一部分保存为一张图片呢

版本3.3,因为我要做的是随机生成的一个物品,比如一个人物有各种衣服,我需要把随机生成的这个拼好的图片截屏保存发给服务器,网上找到的都是之前老版本的方法,那位大神能帮我一下,谢谢啦

我先插个眼。。

web的还好

保存base64就行了

1赞

targetTexture2D 没有 getGFXTexture()这个方法呢

类型“cocos_core_assets_texture_base_TextureBase”上不存在属性“getHtmlElementObj”。

报错不用管web能运行

createSprite() {
        const canvas = game.canvas;
        const width = canvas.width;
        const height = canvas.height;

        // 新截图占原图的比例
        const rect = {x:0.1, y:0.1, w:0.2, h:0.2};

        const w = width * rect.w;
        const h = height * rect.h;
        const x = width * rect.x;
        const y = height * rect.y;

        const new_canvas = document.createElement('canvas');
        const new_canvas_ctx = new_canvas.getContext('2d');
        new_canvas.width = w;
        new_canvas.height = h;
        new_canvas_ctx.drawImage(canvas, x, y, w, h,0, 0, w, h);
        const dataURL = canvas.toDataURL("image/png");
       // base64转化可下载的文件
        let arr = dataURL.split(',');
        let bstr = atob(arr[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }

        // 下载
        let downloadEl = document.createElement('a');
        downloadEl.id = 'file_download';
    
        // 绑定文件信息
        downloadEl.href = window.URL.createObjectURL(new Blob([u8arr], { type: "image/png" }));
        downloadEl.download = "测试";
        downloadEl.click();
        window.URL.revokeObjectURL(downloadEl.href);
}
2赞

这是我的代码现在截屏是一张全黑的图片

你的做法跟我做法或者原理一致吗?

我觉得是一样的呢,我把你的test sprite 换成了 game.canvas

我传入的是HTML Image呀,你传入的是HTMLCanvasElement?

嗯,我要的是canvas好些图片拼在一起的截图,那这怎么实现呢

import { _decorator, Component, Sprite, RenderTexture, gfx, director, Camera, view } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TTTT')
export class TTTT extends Component {

    @property(Camera)
    private camera: Camera = null;

    public onLoad(): void {
        window["TTTT"] = this;
    }

    private copyRenderTexture(rt: RenderTexture): ArrayBuffer {
        let arrayBuffer = new ArrayBuffer(rt.width * rt.height * 4);
        let region = new gfx.BufferTextureCopy();
        region.texOffset.x = 0;
        region.texOffset.y = 0;

        region.texExtent.width = rt.width;// 640
        region.texExtent.height = rt.height;// 1136

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

        return arrayBuffer;
    }

    public download(): void {
        let canvas = document.createElement("canvas");
        let ctx = canvas.getContext("2d");
        let size = view.getVisibleSize();
        let width = Math.round(size.width);
        let height = Math.round(size.height);

        canvas.width = width;
        canvas.height = height;
        // 此方案为:场景存在一个专门负责截图的相机,它可以渲染任何参与截图的元素,并需要为此相机绑定一个RenderTexture实例。
        let arrayBuffer = this.copyRenderTexture(this.camera.targetTexture);
        let imageU8Data = new Uint8Array(arrayBuffer);
        let length = imageU8Data.length;
        let newU8 = new Uint8Array(length);
        // 翻转图片,原图第i行=新图第length-i-1行
        for (let i = 0; i < length; i++) {
            let row02 = parseInt(i / (4 * width) + "");
            let row01 = height - row02 - 1;
            let index = row01 * width * 4 + i % (4 * width);
            newU8[i] = imageU8Data[index];
        }

        let rowBytes = width * 4;
        let rowBytesh = height * 4;

        // 绘制图片数据
        for (let row = 0; row < rowBytesh; row++) {
            let sRow = row;
            let imageData = ctx.createImageData(width, 1);
            let start = sRow * rowBytes;
            for (let i = 0; i < rowBytes; i++) {
                imageData.data[i] = newU8[start + i];
            }

            ctx.putImageData(imageData, 0, row);
        }

        // 拿到base64
        let dataURL = canvas.toDataURL("image/png", 0.1);

        // base64转化可下载的文件
        let arr = dataURL.split(',');
        let bstr = atob(arr[1]);
        let n = bstr.length - 1;
        let u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }

        // 下载
        let downloadEl = document.getElementById('file_download');
        if (!downloadEl) {
            downloadEl = document.createElement('a');
            downloadEl.id = 'file_download';
        }
        // 绑定文件信息
        downloadEl.href = window.URL.createObjectURL(new Blob([u8arr], { type: "image/png" }));
        downloadEl.download = "测试";
        downloadEl.click();
        window.URL.revokeObjectURL(downloadEl.href);
    }
}


1赞

这个方案,我测试了web端是可行的。并且根据参考资料,其他平台也支持,不过需要自己去实现~

现在引擎就是很多东西都是web可以实现原生端不行

NewProject.zip (1.3 MB)
上传了一个Demo。下面是测试结果。

1赞

按钮显示偏黑色是因为Button的Transition模式
image

谢谢,我的问题帮我解决了

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。