¿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
0significa desenfoque (negro) y>=1significa no desenfoque (blanco). Inicie esta parte con un valor lo suficientemente grande, por ejemplow=100pí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.0pero hágalo solo para los píxeles de destino donde la máscara es
==0despué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
NvecesNdetermina la profundidad del gradiente de desenfoque / no desenfoque, lawes 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
1a255el resto es negro, el ancho del gradiente es
dry 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ón2x20.50,0.25 0.25,0.00 -
umbral de bucle de
1a255por 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,ystamaño de la imagen en píxeles -
p[y][x].ddes 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