Android Renderscript,从位图中删除白色/白色背景
我正在开发一个基于图片的应用程序,但由于Renderscript出现问题而被阻止 理论上我的目的很简单,我想从用户加载的图像中删除白色背景,在另一张我设置为背景的图像上显示它们。更具体地说,我想模拟的是在纸画布(也是图片)上打印用户上传的图形的效果,具有逼真的效果 我不能假设用户能够通过alpha通道上传漂亮的PNG,其中一个要求是使用JPG操作 我一直在尝试用RenderScripts解决这个问题,用类似这样的东西将alpha 0设置为R、G和B都等于或大于240的任何值:Android Renderscript,从位图中删除白色/白色背景,android,image,image-processing,bitmap,renderscript,Android,Image,Image Processing,Bitmap,Renderscript,我正在开发一个基于图片的应用程序,但由于Renderscript出现问题而被阻止 理论上我的目的很简单,我想从用户加载的图像中删除白色背景,在另一张我设置为背景的图像上显示它们。更具体地说,我想模拟的是在纸画布(也是图片)上打印用户上传的图形的效果,具有逼真的效果 我不能假设用户能够通过alpha通道上传漂亮的PNG,其中一个要求是使用JPG操作 我一直在尝试用RenderScripts解决这个问题,用类似这样的东西将alpha 0设置为R、G和B都等于或大于240的任何值: #pragma v
#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);
}
但结果并不令人满意,主要有两个原因:
- 如果照片的背景上没有白色渐变,脚本会产生难看的噪音效果
- 阴影靠近边缘的图像会在靠近边缘处获得噪波效果
我不能使用PorterDuff和multiply,因为背景和前景有不同的维度,而且我需要能够在应用效果后在背景画布上拖动上传的图像。如果我将图像与背景区域相乘,移动结果图像将导致背景部分也随之移动。如果我没有弄错,您需要根据相邻像素的线条/块确定当前像素是否可以是白色背景 你可以试试这个用法。例如,要处理原始代码中的一行,请执行以下操作:
#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);
uint32_t width = rsAllocationGetDimX(gIn);
// E.g: Processing a line from x to x+5.
bool isBackground = true;
for (uint32_t i=0; i<=5 && x+i<width; i++) {
uchar4 nPixel_u4 = rsGetElementAt_uchar4(gIn, x+i, y);
float4 nPixel_f4 = rsUnpackColor8888(nPixel_u4);
if(nPixel_f4.r <= th || nPixel_f4.g <= th || nPixel_f4.b <= th) {
isBackground = false;
break;
}
}
if (isBackground) {
f4.a = 0.0f;
*v_out = rsPackColorTo8888(f4);
}
}
void filter() {
rsForEach(gScript, gIn, gOut);
}
布拉格语版本(1)
#pragma rs java_包名称(mypackagename)
卢比;
rs_分配痛风;
rs_脚本gScript;
常量静态浮点th=239.f/256.f;
空根(常数uchar4 v_in,常数uchar4 v_out,常数void*usrData,uint32_t x,uint32_t y){
浮动4 f4=RS8888(*v_英寸);
uint32_t宽度=RSAllocatingETDIMX(gIn);
//例如:处理从x到x+5的一行。
bool isBackground=true;
对于(Unt32),i=0;谢谢苗,它看起来很有前途。我正在尝试,我接受你的答案。我已经暂时赞成了:)你也可以考虑通过可调用(即Fiter())来调用它,而使用反射的java前缀()。您还可以将函数更改为按值传递,因为您根本不使用指针和/或usrData。