cocos3.8.6相机截屏方法
获取场景中的主相机,渲染相机纹理像素,处理翻转后保存图片(IOS无需翻转)
captureScreen(filename: string) {
const visibleSize = view.getVisibleSize();
const width = Math.floor(visibleSize.width);
const height = Math.floor(visibleSize.height);
// 放在应用私有目录中,无需额外申请读写权限
const savePath = `${native.fileUtils.getWritablePath()}${filename}.jpg`;
// 清理旧文件
if (native.fileUtils.isFileExist(savePath)) {
native.fileUtils.removeFile(savePath);
}
// 获取主相机
const mainCamera = director.getScene().getComponentInChildren(Camera);
if (!mainCamera) {
console.log('截屏失败');
return;
}
// 创建渲染纹理
const texture = new RenderTexture();
texture.reset({ width, height });
// 创建临时相机
const tempNode = new Node();
tempNode.parent = director.getScene();
const tempCamera = tempNode.addComponent(Camera);
tempNode.setWorldPosition(width / 2, height / 2, 1000);
// 手动复制相机设置
tempCamera.projection = mainCamera.projection;
tempCamera.orthoHeight = mainCamera.orthoHeight;
tempCamera.near = mainCamera.near;
tempCamera.far = mainCamera.far;
tempCamera.clearFlags = mainCamera.clearFlags;
tempCamera.visibility = mainCamera.visibility;
tempCamera.priority = mainCamera.priority + 1;
tempCamera.targetTexture = texture;
director.once(Director.EVENT_AFTER_DRAW, () => {
try {
const data = texture.readPixels();
// 安卓需要翻转图片,IOS并不需要
const picData = sys.os === sys.OS.IOS ? data : this.flipImageY(data, width, height);
native
.saveImageData(picData, width, height, savePath)
.then(() => {
// 清理资源
tempNode.destroy();
texture.destroy();
})
.catch((e) => {
console.log('截屏保存失败');
tempNode.destroy();
texture.destroy();
});
} catch (e) {
console.log('截屏渲染失败');
tempNode.destroy();
texture.destroy();
}
});
}
// 翻转图片
flipImageY(data: Uint8Array, width: number, height: number) {
const pixels = new Uint8Array(width * height * 4);
const rowBytes = width * 4;
const maxRow = height - 1;
for (let row = 0; row < height; row++) {
const srow = maxRow - row;
const start = srow * rowBytes;
const reStart = row * rowBytes;
for (let i = 0; i < rowBytes; i++) {
pixels[i + reStart] = data[start + i];
}
}
return pixels;
}