【发布时间】:2016-08-06 10:39:54
【问题描述】:
我正在开发基于图片的应用程序,但由于 Renderscript 的问题而被阻止。
理论上我的目的很简单,我想从用户加载的图像中删除白色背景,以在我设置为背景的另一张图像上显示它们。更具体地说,我想要模拟在纸画布(也是图片)上打印用户上传的图形的效果,并具有逼真的效果。
我不能假设用户能够上传带有 alpha 通道的漂亮 PNG,其中一项要求是使用 JPG 进行操作。
我一直在尝试使用 RenderScripts 解决这个问题,使用类似这样的方法将 alpha 0 设置为 R、G 和 B 都等于或大于 240 的任何值:
#pragma version(1)
#pragma rs java_package_name(mypackagename)
rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;
const static float th = 239.f/256.f;
void root(const uchar4 v_in, uchar4 v_out, const void* usrData, uint32_t x,uint32_t y){
float4 f4 = rsUnpackColor8888(*v_in);
if(f4.r > th && f4.g > th && f4.b > th)
{
f4.a = 0;
}
*v_out = rsPackColorTo8888(f4);
}
void filter() {
rsForEach(gScript, gIn, gOut);
}
但结果并不令人满意,主要有两个原因:
- 如果照片的背景不是白色渐变,则脚本会产生丑陋的噪点效果
- 阴影靠近边缘的图像在靠近边缘时会产生噪点效果
我知道从 alpha 0 传递到 alpha 1 太极端了,我尝试了不同的解决方案,包括当 R、G、B 分量的总和减少时线性增加 alpha,但我周围仍然有嘈杂的像素和块。
如果是纯白色或常规背景(例如 Google 主页的快照),它可以完美运行,但如果是照片,则远远不能接受。
我认为,如果我能够处理一个“行”像素或一个“块”像素而不是单个像素,则可以更容易检测平坦背景并避免遇到渐变,但我对渲染脚本了解不够。
谁能指出我正确的方向?
PS
我不能使用 PorterDuff 和乘法,因为背景和前景具有不同的尺寸,而且我需要能够在应用效果后在背景画布周围拖动上传的图像。如果我将图像与移动结果图像的背景区域相乘,则会导致背景的一部分也移动。
【问题讨论】:
标签: android image image-processing bitmap renderscript