测试例子:capture_case.zip (150.0 KB)
这个问题我几年前就提过了,现在完美的解决方法如下(即在截出来的图后面手动叠一个不透明的纯白背景,把所有透明度阈值minOpacity以上的像素都变成不透明的):
// 透明图片与背景混合
let data: any = new Uint8Array(cameraWidth * cameraHeight * 4);
renderTexture.readPixels(data, 0, 0, cameraWidth, cameraHeight);
let halfCameraHeight = Math.ceil(cameraHeight / 2);
let minOpacity = 5;
for (let i = 0; i < cameraWidth; i++) {
for (let j = 0; j <= halfCameraHeight; j++) {
// 修复截图上下反向问题
for (let k = 0; k < 4; k++) {
let w1 = i * 4 + j * cameraWidth * 4 + k; // 从上往下的像素RGBA位置
let w2 = i * 4 + (cameraHeight - j - 1) * cameraWidth * 4 + k; // 从下往上的像素RGBA位置
if (k < 3) { // 当前位置为RGB值
if (data[w1 + 3 - k] >= minOpacity) {
data[w1] = Math.floor(data[w1] * data[w1 + 3 - k] / 255) + 255 - data[w1 + 3 - k];
}
if (w1 !== w2 && data[w2 + 3 - k] >= minOpacity) { // 总行数为奇数时中间那一行的w1===w2,不需要处理两遍
data[w2] = Math.floor(data[w2] * data[w2 + 3 - k] / 255) + 255 - data[w2 + 3 - k];
}
} else { // 当前位置为Alpha值
data[w1] = data[w1] >= minOpacity ? 255 : 0;
if (w1 !== w2) { // 总行数为奇数时中间那一行的w1===w2,不需要处理两遍
data[w2] = data[w2] >= minOpacity ? 255 : 0;
}
}
if (w1 !== w2) { // 总行数为奇数时中间那一行的w1===w2,不需要交换
let temp = data[w1];
data[w1] = data[w2];
data[w2] = temp;
}
}
}
}
2赞
几年前就反馈了,官方没有任何解释吗
这个方法可以解决透明的问题,但是颜色跟原本效果有差异。
有解释,你点我上面回复的“提过”两个字进去看。
是按照图片放在白色背景上处理的,如果你原图是放在白色背景上,就没有差异。如果你想改别的颜色背景可以自己改下面的颜色值。
底图并非纯色,所以无论叠加什么颜色都还是会有差异的
那你就把底图参与截图就好了啊,截图区域设为不包括底图的原节点大小
多个层级有半透明,层层叠加的效果,无论怎么样还是会有一点差异,不过一般不用纠结那么细,简单处理掉半透明穿透的问题就够了,色差不仔细观察一般不太会注意到的。
3Q 3Q 3Q
该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。
