如何在Android中模糊图像的某些部分?

问题描述:

我正在一个项目中工作,我必须清楚地显示图像的某些部分,并使图像的其余部分模糊。模糊应该由滑块管理。意味着它可以增加或减少。最终结果图像应该在下面看起来相似。

I am working in a project where I have to show some portion of the image clear and make rest part of the image blur. The blur should be managed by slider. Means it can be increase or decrease. The final result image should look alike below.

在我研究期间,我发现下面的链接很有用

During my research for this I found below links useful


  1. http:/ /blog.neteril.org/blog/2013/08/12/blurring-images-on-android/

https://github.com/kikoso/android-stackblur

http://blog.neteril .org / blog / 2013/08/12 / blurring-images-on-android /

但上述链接中的问题是它们都会使图像模糊。不是图像的某些部分。

But the issue in above links is they all make complete image blur. Not some part of image.

请提出一些解决方案来实现这一目标。在此先感谢。

Kindly suggest some solution to achieve this. Thanks in advance.

做几次蒙面模糊....

do a masked blur few times ....


  1. 创建面具

0 表示模糊(黑色)和> = 1 表示不模糊(白色)。以足够大的值初始化此部分,例如 w = 100 像素

0 means blur (black) and >=1 means not blur (white). Init this part by big enough value for example w=100 pixels

创建蒙版模糊功能

只是一个常见的卷积,有一些矩阵,如

just a common convolution with some matrix like

0.0 0.1 0.0
0.1 0.6 0.1
0.0 0.1 0.0

但仅适用于面具的目标像素是 == 0 图像模糊后也模糊了面具。这应该稍微扩大白色区域(每次迭代按像素增加但在边界上丢失幅度,这就是为什么 w> 1 )。

but do it only for target pixels where mask is ==0 after image is blurred blur also the mask. This should enlarge the white area a bit (by pixel per iteration but losing magnitude on borders that is why w>1).

循环子弹#2 N

loop bullet #2 N times

N 确定模糊/非模糊渐变深度 w 只是为了确保毛刺蒙版会增长...每次模糊掩码会增加其白色部分

N determines blur/non-blur gradient depth the w is only to assure that burred mask will grow... Each time the blur mask will increase its white part

这应该可以解决问题,你也可以使用掩码的扩张代替模糊了它。

That should do the trick, You can also use dilatation of the mask instead of blurring it.

[edit1]实施

玩了这个今天发现面具不够光滑,所以我改变了算法(这里是我的代码C ++):

Have played with this a bit today and found out that the mask is not growing enough with smooth so I change the algo a bit (here mine code C++):

picture pic0,pic1,pic2;
    // pic0 - source
    // pic1 - output
    // pic2 - mask
int x0=400,y0=330,r0=100,dr=200;
    // x0,y0,r0 - masked area
    // dr - blur gradient size
int i,r;

// init output as sourceimage
pic1=pic0;
// init mask (size of source image) with gradient circles
pic2.resize(pic0.xs,pic0.ys);
pic2.clear(0);
for (i=1;i<=255;i++)
    {
    r=r0+dr-((dr*i)>>8);
    pic2.bmp->Canvas->Brush->Color=TColor(i<<16); // shifted because GDI has inverse channel layout then direct pixel access
    pic2.bmp->Canvas->Pen  ->Color=TColor(i<<16);
    pic2.bmp->Canvas->Ellipse(x0-r,y0-r,x0+r,y0+r);
    }
for (i=1;i<255;i+=10) pic1.rgb_smooth_masked(pic2,i);

这里顺畅的功能:

//---------------------------------------------------------------------------
void picture::rgb_smooth_masked(const picture &mask,DWORD treshold)
    {
    int i,x,y;
    color *q0,*q1,*m0,c0,c1,c2;
    if ((xs<2)||(ys<2)) return;
    for (y=0;y<ys-1;y++)
        {
        q0=p[y  ]; m0=mask.p[y];
        q1=p[y+1];
        for (x=0;x<xs-1;x++)
         if (m0[x].dd<treshold)
            {
            c0=q0[x];
            c1=q0[x+1];
            c2=q1[x];
            for (i=0;i<4;i++)
             q0[x].db[i]=DWORD((DWORD(c0.db[i])+DWORD(c0.db[i])+DWORD(c1.db[i])+DWORD(c2.db[i]))>>2);
            }
        }
    }
//---------------------------------------------------------------------------




  1. 创建渐变蒙版,其中的圆圈颜色从 1 至 255

  1. create gradient mask with circles increasing in color from 1 to 255

其余为黑色渐变width是 dr 并确定平滑清晰度。

rest is black the gradient width is dr and determine the smoothing sharpness.

创建平滑蒙版,带蒙版和阈值

平滑掩模像素所在的所有像素<阈。查看函数 rgb_smooth_masked 。它使用 2x2 卷积矩阵

smooth all pixels where mask pixel is < threshold. See the function rgb_smooth_masked. It uses 2x2 convolution matrix

0.50,0.25
0.25,0.00


  • 来自 1 $的循环阈值c $ c>到 255 一步

  • loop threshold from 1 to 255 by some step

    该步骤决定图像模糊强度。

    the step determines the image blur strength.

    最后这里有一些视觉效果,这是我用相机拍摄的源图像:

    And finally here some visual results this is source image I taken with my camera:

    这里是左边的输出和右边的掩码:

    And here the output on the left and mask on the right:

    蓝色表示值< 256 (B是最低的8位颜色)

    the blue color means values < 256 (B is lowest 8 bits of color)

    我使用自己的图片类来处理图片,所以有些成员是:

    I use my own picture class for images so some members are:


    • xs,ys 图像大小(以像素为单位)

    • p [y] [x] .dd (x,y)的像素位置为32位整数类型

    • 清除(颜色) - 清除整个图像

    • 调整大小(xs ,ys) - 将图片大小调整为新分辨率

    • xs,ys size of image in pixels
    • p[y][x].dd is pixel at (x,y) position as 32 bit integer type
    • clear(color) - clears entire image
    • resize(xs,ys) - resizes image to new resolution