* 출처
: https://woodongwoo.tistory.com/56
: https://blog.naver.com/wldudrbgur/110179642609
* 참고할만한 자료
: https://m.blog.naver.com/copyeye/220230065601
안드로이드 간단한 BlurDrawable 구현
안드로이드에는 Blur 기능이 없다. 이미지가 있으면 해당 이미지에 대한 Blur기능은 있다. 하지만 뒤에 나타난 뷰들을 Blur 할 수 있는 기능은 없다.
iOS는 어떻게 Blur가 지원되는 지 모르겠으나. 안드로이드는 구조적으로 Blur기능 구현이 어렵다.
안드로이드에서 View를 나타내기 위해서 Canvas를 이용하여 그리도록 되어 있다.
Canvas는 사용하는 방법에 따라 여러가지로 구현이 가능하다.
Bitmap에 Canvas를 이용해서 그림을 그릴 수도 있다. 그런데 안드로이드 View에서 사용하는 Canvas가 지정한 대상에 접근이 불가능하다.
그려지는 대상이 Native에 대상이 있기 때문이다. 어쩌면 NDK를 활용하면 접근이 가능할 수도 있을 것 같다.
이 이상으로 알아보기 위해서는 Android OS소스 분석을 해야하기 때문에.. 여기 까지만 알아봤다.
그럼 안드로이드에서 Blur기능을 구현하기가 어렵다는 것 까지 알아보았다. 어렵다가 꼭 불가능하다는 뜻은 아니다. 어려워도 가능하다.
여러가지 방법이 있겠지만 나는 가장 간단한 방법을 선택했다. Blur의 배경이 될 뷰의 스크린 샷을 뜨고 원하는 부분의 이미지를 잘라서
Blur 효과를 추가해서 그려주면 된다. 간단하죠?
자 그럼 소스로 넘어가서 보겠습니다.
일단 BlurDrawable의 사용 방법은 최대한 간단하게 구현하려고 계획했습니다. 그래서 먼저 다음과 같이 코드를 짜고 작업을 시작했습니다.
------------
1.
BlurDrawable bd =
new
BlurDrawable();
2.
bd.setBGView(bv);
3.
bd.setView(v);
4.
v.setBackgroundDrawable(bd);
------------
BlurDrawable을 선언하고 배경이 되는 View와 대상이 되는 View를 넣어주고 BackgroudDrawable로 넣어주면 끝이다.
사용 방법은 간단하게 정리를 했습니다!
자 이제 다음으로 BlurDrawable이 어떻게 구현됐는지 살펴보겠습니다.
먼저 배경이 될 View와 Blur이미지를 나타낼 View를 만들겠습니다.
-----------
01.
<<
gs
id
=
"70fe04bf-fde3-4b0d-aace-edffa6701804"
ginger_software_uiphraseguid
=
"453136bb-677e-4318-85b8-dd48070e124d"
class
=
"GINGER_SOFTWARE_mark"
>?</
gs
><
gs
id
=
"9c17ca22-bec0-47a6-9d6d-16774e605ded"
ginger_software_uiphraseguid
=
"453136bb-677e-4318-85b8-dd48070e124d"
class
=
"GINGER_SOFTWARE_mark"
>xml</
gs
> version="1.0" encoding="utf-8"?>
02.
<
RelativeLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
03.
android:layout_width
=
"match_parent"
04.
android:layout_height
=
"match_parent"
>
05.
06.
<
RelativeLayout
07.
android:id
=
"@+id/background"
08.
android:layout_width
=
"wrap_content"
09.
android:layout_height
=
"wrap_content"
10.
android:layout_alignParentBottom
=
"true"
11.
android:layout_alignParentLeft
=
"true"
12.
android:layout_alignParentRight
=
"true"
13.
android:layout_alignParentTop
=
"true"
14.
android:background
=
"@drawable/hydrangeas"
>
15.
</
RelativeLayout
>
16.
17.
<
LinearLayout
18.
android:id
=
"@+id/imageContainer"
19.
android:layout_width
=
"wrap_content"
20.
android:layout_height
=
"wrap_content"
21.
android:layout_centerInParent
=
"true"
22.
android:orientation
=
"vertical"
>
23.
24.
<
ImageView
25.
android:id
=
"@+id/image"
26.
android:layout_width
=
"100dp"
27.
android:layout_height
=
"100dp"
/>
28.
</
LinearLayout
>
29.
30.
</
RelativeLayout
>
-----------
배경이 되는 View는 RelativeLayout으로 구현이 되어 있습니다. 그리고 Blur를 표시할 View는 ImageView로 구현이 되어 있습니다. 굳이 ImageView로 만들 필요는 없습니다. 여기서 주의할 점은 표시할 View가 배경이 될 View에 포함이 되면 안된다는 것입니다. 이유는 View가 Update되면 Blur가 된 곳에 또 Blur를 하게 되기 때문입니다.
다음으로 BlueDrawable을 어떻게 구현했는지 보여드리겠습니다. BlurDrawable은 다해서 100줄이 안돼서 그냥 코드 전체를 놓고 설명하겠습니다.
-------------
01.
public
class
BlurDrawable
extends
Drawable {
02.
03.
private
View bgView;
04.
private
View view;
05.
06.
private
int
size =
6
;
07.
private
int
squal = size*size;
08.
private
int
[] pixels =
new
int
[squal];
09.
Bitmap viewBitmap;
10.
11.
@Override
12.
public
void
draw(Canvas canvas) {
13.
bgView.setDrawingCacheEnabled(
true
);
14.
Bitmap bm = bgView.getDrawingCache();
15.
if
(bm ==
null
){
16.
return
;
17.
}
18.
19.
if
(viewBitmap ==
null
){
20.
viewBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);
21.
}
22.
23.
Rect pRect =
new
Rect();
24.
Rect cRect =
new
Rect();
25.
26.
bgView.getGlobalVisibleRect(pRect);
27.
view.getGlobalVisibleRect(cRect);
28.
29.
int
sumR =
0
, sumG =
0
, sumB =
0
;
30.
int
red =
0
, green =
0
, blue =
0
;
31.
32.
for
(
int
i = cRect.left - pRect.left; i < cRect.right - pRect.left; i++){
33.
for
(
int
j = cRect.top - pRect.top; j < cRect.bottom - pRect.top; j++){
34.
bm.getPixels(pixels ,
0
, size, i - size/
2
, j - size/
2
, size, size);
35.
for
(
int
k =
0
; k < squal; k++){
36.
sumR += (pixels[k] >>
16
) &
0xFF
;
37.
sumG += (pixels[k] >>
8
) &
0xFF
;
38.
sumB += pixels[k] &
0xFF
;
39.
}
40.
red = (sumR / squal);
41.
green = (sumG / squal);
42.
blue = (sumB / squal);
43.
int
pixel =
0xFF000000
+ (red <<
16
) + (green <<
8
) + blue;
44.
viewBitmap.setPixel(i - (cRect.left - pRect.left), j - (cRect.top - pRect.top), pixel );
45.
sumR = sumG = sumB =
0
;
46.
red = green = blue =
0
;
47.
}
48.
}
49.
50.
canvas.drawBitmap(viewBitmap,
null
, getBounds(),
null
);
51.
}
52.
53.
public
View getView() {
return
view; }
54.
public
void
setView(View view) {
this
.view = view; }
55.
public
View getParentView() {
return
bgView; }
56.
public
void
setBGView(View parentView) {
this
.bgView = parentView; }
57.
58.
@Override
public
int
getOpacity() {
return
0
; }
59.
@Override
public
void
setAlpha(
int
alpha) { }
60.
@Override
public
void
setColorFilter(ColorFilter cf) { }
61.
}
-------------
방법은 간단합니다. bgView에서 캡쳐화면을 가져옵니다. DrawingCashe를 가져오는 것입니다.
setDrawingCacheEnabled()함수와 getDrawingCache()함수를 이용하면 간단하게 Bitmap 형태로 가져올 수 있습니다.
다음으로 Bitmap 이미지를 하나 만듭니다. 이 이미지는 Blur를 나타낼 View의 사이즈에 맞춰서 만들도록 되어 있습니다.
각 뷰의 위치와 사이즈를 나타내는 Rect를 가져옵니다. getGlobalVisibleRect() 함수를 활용하면 쉽게 가져올 수 있습니다.
BG View와 Blur View의 상대 위치를 파악해서 해당 부분에서 사용될 이미지를 추출하기 위해서입니다.
다음으로 for루프 안에 있는 내용은 Blur 로직을 간단하게 구현한 것입니다. Blur로직은 원하시는 로직으로 바꾸셔도 무방합니다.
마지막으로 bitmap을 그리면 됩니다.
간단하죠?
발전을 더욱 시키면 좋겠지만.. 재미삼아 만든 것이라.. 여기까지만 하겠습니다.
소스입니다. 참고하세요.
안드로이드 Blur 효과 내기
디자이너 친구의 부탁으로 안드로이드에서 블루어 효과를 낼 수있냐고 물어봤다
찾아보니 윈도우의 aero glass효과와 비슷한 개념인거 같았다.
구글링을 해보니 대부분
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes(); |
의 답을 내놓았고
내생각엔 기본으로 지원해주네~ 하고 적용해봤만 효과 적용 안됨...
다시 검색해보니
"The field WindowManager.LayoutParams.FLAG_BLUR_BEHIND is deprecated".
더이상 지원하지 않는 기능이란다.. 여기저기 검색해보니 구글느님이 답을 주셨습니다.
능력자분이 만든 클래스가 있더라고요 *첨부파일을 확인해주세요
해당 클래스 추가하고
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 1; Bitmap newImg = Blur.fastblur(this, image, 12); |
이 비트맵을 원하는 뷰에 배경으로 넣으면 되요 ㅎㅎㅎ
끝.
'IT_Programming > Android_Java' 카테고리의 다른 글
[펌] Making Multi-process Android applications. (0) | 2016.07.12 |
---|---|
[안드로이드] 비콘(Beacon) (0) | 2016.06.30 |
MEDIAPLAYER 음악 재생하기 (0) | 2016.06.07 |
[펌_Android Material Design] EditText의 업글버전? (TextInputEditText+TextInputLayout) 을 써보자 (0) | 2016.06.07 |
[Android] RecyclerView를 이용한 ExpandableListView (0) | 2016.06.03 |