Как размыть часть изображения в Android?
Я работаю в проекте, где я должен показать некоторую часть изображения ясно и сделать остальную часть размытия изображения. Размытие должно управляться слайдером. Значит, его можно увеличить или уменьшить. Изображение конечного результата должно выглядеть одинаково ниже.
во время моего исследования для этого я нашел ниже ссылки полезные
http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/
http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/
но вопрос в выше ссылок они все делают полной размытости изображения. Не какая-то часть образа.
пожалуйста, предложить некоторые решение для достижения этого. Спасибо заранее.
1 ответов
сделайте размытие в маске несколько раз ....
-
создать маску
0
означает размытие (черный) и>=1
означает не размытие (белый). Init эту часть достаточно большим значением, напримерw=100
пиксели -
создать маскированную функцию размытия
просто общая свертка с некоторой матрицей, такой как
0.0 0.1 0.0 0.1 0.6 0.1 0.0 0.1 0.0
но сделайте это только для цели пиксели, где маска
==0
после изображение размытое пятно и маски. Это должно немного увеличить белую область (на пиксель за итерацию, но потерять величину на границах, поэтомуw>1
). -
петля пуля #2
N
времениN
определяет глубину градиента размытия/не-размытияw
только заверить, что картавить маска будет расти... Каждый раз, когда маска размытия будет увеличивать свой белый цвет часть
это должно сделать трюк, вы также можете использовать расширение маски вместо ее размывания.
[edit1] реализации
поиграли с этим немного сегодня и выяснили, что маска недостаточно растет с гладкой, поэтому я немного меняю algo (здесь мой код 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
to255
rest черный ширина градиента
dr
и определите сглаживающую резкость. -
создать гладкую маскировку с маской и порогом
сгладить все пиксели, где пиксель маски rgb_smooth_masked. Он использует
2x2
матрица конволюции0.50,0.25 0.25,0.00
-
петли порог из
1
для255
каким-то шагомшаг определяет силу размытия изображения.
и, наконец, здесь некоторые визуальные результаты это исходное изображение, которое я взял с моей камерой:
и вот выход слева и маска справа:
синий цвет означает values < 256
(Б нижних 8 бит цвет)
я использую свой собственный класс изображения для изображений, так что некоторые члены:
-
xs,ys
размер изображения в пикселях -
p[y][x].dd
пиксель на(x,y)
позиция как 32-битный целочисленный тип -
clear(color)
- удаляет все изображения -
resize(xs,ys)
- изменение размера изображения до нового разрешения