¿Cómo desenfocar una parte de la imagen en Android?
image-processing android-canvas (1)
Estoy trabajando en un proyecto donde tengo que mostrar una parte de la imagen clara y hacer que el resto de la imagen sea borrosa. El desenfoque debe ser gestionado por el control deslizante. Significa que puede aumentar o disminuir. La imagen del resultado final debería parecerse a continuación.
Durante mi investigación para esto, encontré los siguientes enlaces útiles
-
http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/
-
http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/
Pero el problema en los enlaces anteriores es que todos hacen que la imagen se vea borrosa. No es una parte de la imagen.
Amablemente sugiera alguna solución para lograr esto. Gracias por adelantado.
hacer un desenfoque enmascarado varias veces ...
-
crear máscara
0
significa desenfoque (negro) y>=1
significa no desenfoque (blanco). Inicie esta parte con un valor lo suficientemente grande, por ejemplow=100
píxeles -
crear función de desenfoque enmascarado
solo una convolución común con alguna matriz como
0.0 0.1 0.0 0.1 0.6 0.1 0.0 0.1 0.0
pero hágalo solo para los píxeles de destino donde la máscara es
==0
después de que la imagen se vea borrosa, desenfoque también la máscara. Esto debería agrandar un poco el área blanca (por píxel por iteración pero perdiendo magnitud en los bordes, por esow>1
). -
bala de bucle # 2
N
vecesN
determina la profundidad del gradiente de desenfoque / no desenfoque, law
es solo para asegurar que la máscara con burros crecerá ... Cada vez que la máscara de desenfoque aumente su parte blanca
Eso debería ser el truco. También puedes usar la dilatación de la máscara en lugar de difuminarla.
[edit1] implementación
Hoy he jugado un poco con esto y descubrí que la máscara no está creciendo lo suficiente con suavidad, así que cambio un poco el algoritmo (aquí el código 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);
Aquí la función suave:
//---------------------------------------------------------------------------
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);
}
}
}
//---------------------------------------------------------------------------
-
crea una máscara de degradado con círculos que aumentan de color de
1
a255
el resto es negro, el ancho del gradiente es
dr
y determina la nitidez de suavizado. -
crear suave enmascarado con máscara y umbral
suaviza todos los píxeles donde el píxel de máscara es <umbral. Vea la función
rgb_smooth_masked
. Utiliza matriz de convolución2x2
0.50,0.25 0.25,0.00
-
umbral de bucle de
1
a255
por algún pasoEl paso determina la intensidad de desenfoque de la imagen.
Y finalmente, aquí algunos resultados visuales, esta es la imagen fuente que tomé con mi cámara:
Y aquí la salida a la izquierda y la máscara a la derecha:
el color azul significa
values < 256
(B es el más bajo de 8 bits de color)
Utilizo mi propia clase de imagen para imágenes, por lo que algunos miembros son:
-
xs,ys
tamaño de la imagen en píxeles -
p[y][x].dd
es un píxel en la posición(x,y)
como tipo entero de 32 bits -
clear(color)
: borra toda la imagen -
resize(xs,ys)
: redimensiona la imagen a una nueva resolución