Android 동적 가우스 퍼 지 효과 튜 토리 얼
최근 에 필 설 프로젝트 의 준 비 를 계속 하고 있 는데 모호 한 효 과 를 사용 해 야 할 수도 있다 는 것 을 고려 하여 고 스 모호 효과 의 실현 을 배 웠 다.비교적 유명한 것 은 바로 FastBlur 와 그 파생 된 최적화 방안,그리고 오늘 말 하고 자 하 는 RenderScript 이다.
이 물건 은 지금 필요 해서 배 우 는 것 이기 때문에 이미지 처리 와 렌 더 링 문 제 는 언급 하지 않 겠 습 니 다.그러나 사용 하 는 과정 에서 서로 다른 방안 이 똑 같은 모호 효 과 를 실현 할 수 있 지만 효율 의 차 이 는 정말 크다 는 것 을 느 낄 수 있다.
이 글 에서 실 현 된 고 스 모호 함 은 아래 의 이 글 에 근거 하여 배 운 것 이 므 로 먼저 추천 합 니 다.본 논문 의 내용 과 내용 은 차이 가 많 지 않 고 조금 상세 하 게 말 했 을 뿐 코드 중의 일부 가 논리 적 이 고 세부 적 인 처 리 를 실현 하도록 수정 했다.그러나 주 체 는 내용 이 변 하지 않 기 때문에 어떤 문장 을 선택해 서 배 워 도 마찬가지다.
이런 고 스 퍼 지 효 과 를 어떻게 실현 하 는 지 살 펴 보 자.
간단하게 얘 기 하 자.Renderscript.
효과 의 실현 은 Renderscript 에 기반 한 것 이기 때문에 먼저 알 아 볼 필요 가 있 습 니 다.
그것 의 공식 문 서 를 보면 매우 현묘 하 게 말한다.우 리 는 조금 만 알 았 으 면 좋 겠 다.
RenderScript is a framework for running computationally intensive tasks at high performance on Android.
렌 더 스 크 립 트 는 안 드 로 이 드 플랫폼 에서 고성능 컴 퓨 팅 을 하 는 프레임 워 크 다.
고성능 컴 퓨 팅 인 만큼 렌 더 스 크 립 트 는 이미지 에 대한 처리 가 매우 강하 기 때문에 이 를 통 해 고 스 퍼 지 를 실현 하 는 것 이 좋 습 니 다.
그럼 어떻게 사용 하나 요?공식 문서 에서 볼 수 있 듯 이 자바 코드 에서 Renderscript 을 사용 하려 면 android.renderscript 또는 android.support.v8.renderscript 의 API 에 의존 해 야 합 니 다.API 가 있 으 니까 훨씬 쉬 워 요.
다음은 사용 절 차 를 간단하게 말씀 드 리 겠 습 니 다.이것 도 공식 문서 의 설명 입 니 다.
문서 의 해석 은 영원히 규칙 적 이 고 이해 하기 어렵다.우 리 는 원래 의 블 로 거 추 수의 긴 코드 와 결합 하여 절 차 를 살 펴 보 자.
/**
* @author Qiushui
* @description
* @revision Xiarui 16.09.05
*/
public class BlurBitmapUtil {
//
private static final float BITMAP_SCALE = 0.4f;
/**
*
*
* @param context
* @param image
* @return
*/
public static Bitmap blurBitmap(Context context, Bitmap image,float blurRadius) {
//
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
//
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
//
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// RenderScript
RenderScript rs = RenderScript.create(context);
// RenderScript
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// RenderScript VM , Allocation
// Allocation , copyTo()
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
// , 25f
blurScript.setRadius(blurRadius);
// blurScript
blurScript.setInput(tmpIn);
//
blurScript.forEach(tmpOut);
// Allocation
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
위 에 고 스 의 모호 한 코드 를 처리 하 는 것 입 니 다.그 중에서 주석 은 매우 상세 하 게 쓰 여 있 고 그림 의 크기 를 조정 하여 처리 하 였 습 니 다.방금 말 한 절 차 를 결합 하면 여러분 은 대략적인 인상 을 가 질 수 있 을 것 입 니 다.정말 모 르 더 라 도 괜 찮 습 니 다.이것 은 도구 류 입 니 다.직접 복사 하면 됩 니 다.물론 원 블 로 거 는 코드 를 바퀴 로 봉 했 고 프로젝트 에서 Gradle 을 직접 인용 할 수도 있 지만 소스 코드 는 봐 야 한다 고 생각 합 니 다.
단순 모호
자,대충 기억 이 나 면 고 스 의 모호 한 효 과 를 어떻게 실현 하 는 지 살 펴 보 자!
우선 프로젝트 에서 원 블 로 거 가 봉 인 된 바퀴 를 직접 인용 할 수 있 습 니 다.
compile 'com.qiushui:blurredview:0.8.1'
인용 하지 않 으 려 면 현재 Module 의 build.gradle 에 다음 코드 를 추가 해 야 합 니 다.
defaultConfig {
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
구축 되면 사용 할 수 있 습 니 다.빌 드 에 실패 하면 minSdkVersion 을 19 로 설정 하면 됩 니 다.어떤 이유 인지 모 르 겠 습 니 다.그러나 StackOverflow 에서 이것 이 bug 라 는 것 을 알 게 되 었 다 면 깊이 연구 할 필요 가 없다.지금 보면 코드 가 실 현 됩 니 다.먼저 레이아웃 파일 에 ImageView 가 있 습 니 다.할 말 이 없습니다.위의 퍼 지 이미지 도구 류 를 통 해 알 수 있 듯 이 고 스 퍼 지 효 과 를 가 진 그림 을 얻 으 려 면 세 가지 가 필요 합 니 다.
문맥:문맥 대상
Bitmap:흐릿 한 그림 이 필요 합 니 다.
BlurRadius:퍼 지 정도
여 기 는 주의해 야 한다.
현재 이 방안 은 PNG 형식의 그림 에 만 적용 되 며,그림 크기 는 좀 작 게 하 는 것 이 좋 습 니 다.코드 에 그림 이 축소 되 었 지만,여전히 멈 출 수 있 습 니 다.
이제 그림 과 퍼 지 정도 만 설정 하면 됩 니 다.
/**
* View
*/
@SuppressWarnings("deprecation")
private void initView() {
basicImage = (ImageView) findViewById(R.id.iv_basic_pic);
//
Bitmap initBitmap = BitmapUtil.drawableToBitmap(getResources().getDrawable(R.raw.pic));
//
Bitmap blurBitmap = BlurBitmapUtil.blurBitmap(this, initBitmap, 20f);
basicImage.setImageBitmap(blurBitmap);
}
실행 도 보기:이 를 통 해 알 수 있 듯 이 그림 은 모호 효 과 를 실 현 했 고 속도 도 매우 빠르다.전체적으로 BlurBitmapUtil.blurBitmap()를 통 해 모호 효 과 를 얻 을 수 있 는 그림 이다.
사용자 정의 퍼 지 컨트롤
원래 블 로 거들 의 바퀴 에는 사용자 정의 Blurred View 가 들 어 있 었 는데 처음에는 사용자 정의 가 필요 없다 고 생각 했 습 니 다.사용자 정의 원인 은 동적 모호 효 과 를 실현 해 야 한 다 는 것 을 발견 했다.
그런데 왜 모호 도 를 수 동 으로 설정 할 수 없 습 니까?그 가 내 놓 은 설명 은:
"위의 코드 를 사용 하여 실시 간 으로 렌 더 링 을 하면 인터페이스 가 심각하게 걸 릴 수 있 습 니 다."
나 도 직접 해 봤 는데,확실히 좀 끊 긴 다.그 가 동적 모호 처 리 를 실현 하 는 방안 은 이렇다.
이 어"그림 을 최대한 흐 리 게 처리 한 다음,희미 해진 그림 위 에 원 도 를 올 려 놓 고,원 도의 투명도(Alpha 값)를 끊임없이 바 꾸 어 동적 모호 효 과 를 구현 한다"고 덧 붙 였 다.
이 방안 은 확실히 동적 효 과 를 교묘 하 게 실현 하지만 이런 방식 을 사용 하려 면 반드시 두 장의 똑 같은 그림 이 있어 야 한 다 는 것 을 주의해 야 한다.코드 에 직접 쓰 려 면 두 개의 컨트롤 이 필요 하 다.그림 이 많 으 면 분명 바람 직 하지 않다.그래서 바퀴 안에 사용자 정의 Blurred View 가 있 습 니 다.
그러나 이 Blurred View 는 잘 봉 인 된 것 이 아니 라 일부 내용 을 삭 제 했 습 니 다.이 유 는 잠시 후에 다시 이야기 하 겠 습 니 다.핵심 코드 부터 살 펴 보 겠 습 니 다.
먼저 사용자 정의 BlurredView 가 RelativeLayout 에 계승 되 었 습 니 다.레이아웃 파일 에서 볼 수 있 습 니 다.그 안에 두 개의 ImageView 가 있 고 겹 쳐 있 습 니 다.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/blurredview_blurred_img"
.../>
<ImageView
android:id="@+id/blurredview_origin_img"
.../>
</FrameLayout>
동시에 일부 속성 도 정의 했다.
<resources>
<declare-styleable name="BlurredView">
<attr name="src" format="reference"/>
<attr name="disableBlurred" format="boolean"/>
</declare-styleable>
</resources>
하 나 는 그림 을 설정 하 는 것 이 고,하 나 는 모호 함 을 사용 하지 않 을 지 설정 하 는 것 입 니 다.마지막 으로 BlurredView 류 입 니 다.코드 는 다음 과 같 습 니 다.대량의 삭제 가 있 고 핵심 코드 만 붙 입 니 다.
/**
* @author Qiushui
* @description View
* @revision Xiarui 16.09.05
*/
public class BlurredView extends RelativeLayout {
/*========== ==========*/
private Context mContext;//
private static final int ALPHA_MAX_VALUE = 255;//
private static final float BLUR_RADIUS = 25f;// ( 0.0 25.0 )
/*========== ==========*/
private ImageView mOriginImg;// ImageView
private ImageView mBlurredImg;// ImageView
private Bitmap mBlurredBitmap;// Bitmap
private Bitmap mOriginBitmap;// Bitmap
/*========== ==========*/
private boolean isDisableBlurred;//
...
/**
*
*
* @param blurredBitmap
*/
public void setBlurredImg(Bitmap blurredBitmap) {
if (null != blurredBitmap) {
mOriginBitmap = blurredBitmap;
mBlurredBitmap = BlurBitmapUtil.blurBitmap(mContext, blurredBitmap, BLUR_RADIUS);
setImageView();
}
}
...
/**
* ImageView
*/
private void setImageView() {
mBlurredImg.setImageBitmap(mBlurredBitmap);
mOriginImg.setImageBitmap(mOriginBitmap);
}
/**
*
*
* @param level , 0~100 .
*/
@SuppressWarnings("deprecation")
public void setBlurredLevel(int level) {
//
if (level < 0 || level > 100) {
throw new IllegalStateException("No validate level, the value must be 0~100");
}
//
if (isDisableBlurred) {
return;
}
//
mOriginImg.setAlpha((int) (ALPHA_MAX_VALUE - level * 2.55));
}
...
}
코드 에서 볼 수 있 듯 이 가장 핵심 적 인 것 은 다음 과 같은 세 가지 방법 이다.setBlurredImg(Bitmap blurredBitmap):그림 을 설정 하고 두 부 복사 합 니 다.
setImageView():두 개의 ImageView 에 해당 하 는 그림 을 설정 하고 내부 호출 합 니 다.
setBlurredLevel(int level):투명 도 를 설정 합 니 다.
사고방식 은 먼저 그림 한 장 을 선택 하고,한 장 은 원화 로 하고,한 장 은 모호 하 게 처 리 된 그림 으로 하 는 것 이다.이 두 장의 그림 을 사용자 정의 BlurredView 의 두 개의 ImageView 에 각각 설정 하고 모호 한 그림 의 투명 도 를 처리 합 니 다.
자,이제 사용자 정의 퍼 지 효과 도 를 쓰 겠 습 니 다.먼저 레이아웃 입 니 다.간단 합 니 다.
<com.blurdemo.view.BlurredView
android:id="@+id/bv_custom_blur"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:src="@raw/pic"
app:disableBlurred="false" />
이 를 통 해 알 수 있 듯 이 그림 을 설정 하고 오픈 퍼 지 를 설정 합 니 다.그러면 저 희 는 Activity 에서 투명 정도 만 설정 하면 됩 니 다.
private void initView() {
customBView = (BlurredView) findViewById(R.id.bv_custom_blur);
//
customBView.setBlurredLevel(100);
}
효과 도 는 위의 그림 과 마찬가지 로 중복 붙 이지 않 습 니 다.이 를 통 해 알 수 있 듯 이 코드 는 매우 간단 하지만 편리 하고 간단 하기 때문에 사용자 정의 View 의 역할 이 아니 라 다음 에 말 할 동적 모호 효과 의 실현 에 작용 한다.동적 모호
우 리 는 먼저 동적 모호 효과 가 무엇 인지 살 펴 보 자.
그림 에서 볼 수 있 듯 이 우리 가 화면 을 만 질 때 배경의 모호 정도 가 달라 진다.퍼 지 정도 와 그 카드 를 직접 설정 하려 면 원 블 로 거들 의 말대 로 두 장의 그림 으로 이 루어 질 수 있다.
대체적인 사고방식 은 위의 그림 을 모호 하 게 처리 하고 아래 의 그림 을 처리 하지 않 은 다음 에 손짓 을 통 해 위의 모호 한 그림 의 투명 도 를 바 꾸 면 된다 는 것 이다.
그래서 앞의 코드 와 거의 같 습 니 다.onTouch Event 방법 을 다시 쓰 면 됩 니 다.
/**
* View
*/
private void initView() {
customBView = (BlurredView) findViewById(R.id.bv_dynamic_blur);
//
initLevel = 100;
customBView.setBlurredLevel(initLevel);
}
/**
*
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveY = ev.getY();
//
float offsetY = moveY - downY;
//
int screenY = getWindowManager().getDefaultDisplay().getHeight() * 10;
//
movePercent = offsetY / screenY;
currentLevel = initLevel + (int) (movePercent * 100);
if (currentLevel < 0) {
currentLevel = 0;
}
if (currentLevel > 100) {
currentLevel = 100;
}
//
customBView.setBlurredLevel(currentLevel);
//
initLevel = currentLevel;
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(ev);
}
코드 에서 볼 수 있 듯 이 여 기 는 손가락 미끄럼 거리 가 화면의 백분율 을 차지 하여 변 경 된 투명 등급 을 계산 하 는 것 으로 코드 가 어렵 지 않 고 쉽게 이해 할 수 있 습 니 다.물론 원 블 로 거 블 로 그 는 진도 조 를 통 해 바 뀌 었 고 괜 찮 았 으 니 군말 하지 않 겠 다.RecylcerView 와 결합
먼저 효과 도 를 살 펴 보면 이 그림 도 원래 블 로 거들 을 본 떠 서 이 루어 진 것 이지 만 약간 다르다.
원래 사용자 정의 BlurredView 에는 배경 그림 의 위 치 를 바 꾸 는 코드 도 몇 개 있 습 니 다.위 에서 아래로 끌 어 내 릴 때 배경 그림 도 이동 할 수 있 기 를 바 랍 니 다.그러나 체험 적 으로 효과 가 좋 지 않 고 위로 끌 어 올 리 는 과정 에서 여백 을 남 기 는 문제 가 발생 할 수 있 습 니 다.
원 블 로 거 는 배경 그림 에 수 동 으로 높이 를 올 리 는 방안 을 제 시 했 지만 이것 은 가장 좋 은 해결 방식 이 아니 었 다.그래서 나 는 이 기능 을 삭제 하고 더 좋 은 실현 방식 을 찾 아 보충 했다.
이제 와 서 어떻게 실현 할 것 인가?먼저 레이아웃 은 바로 아래 층 에서 사용자 정의 BlurredView 입 니 다.위 에 있 는 RecylcerView,RecylcerView 는 두 개의 Type 이 있 습 니 다.하 나 는 머리 레이아웃 이 고 하 나 는 아래 목록 입 니 다.간단 합 니 다.상세 하 게 말 하지 않 겠 습 니 다.
중점 은 여전히 동적 모호 의 실현 이다.위의 동적 모호 에서 우 리 는 onTouch Event 를 다시 쓰 는 방법 을 취 했다.그러나 여 기 는 바로 RecylcerView 이다.우 리 는 그의 스크롤 감청,즉 onScroll Listener 에 따라 동적 투명 도 를 바 꿀 수 있다.핵심 방법 은 다음 과 같다.
//RecyclerView
mainRView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//
mScrollerY += dy;
//
if (Math.abs(mScrollerY) > 1000) {
mAlpha = 100;
} else {
mAlpha = Math.abs(mScrollerY) / 10;
}
//
recyclerBView.setBlurredLevel(mAlpha);
}
});
코드 는 매우 간단 합 니 다.바로 onScrolled 방법 에서 투명 도 를 계산 하고 동적 으로 바 꾸 는 것 입 니 다.원 리 를 파악 하면 실현 하기 가 쉽 습 니 다.총결산
앞의 모든 동적 그림 을 보면 운행 이 비교적 빠 르 지만 저 는 Android Monitor 에서 보 았 습 니 다.처음에 퍼 지 기 를 시 작 했 을 때 GPU 가 렌 더 링 하 는 시간 이 길 기 때문에 성능 이 좋 지 않 을 수 있 습 니 다.
물론 시 뮬 레이 터 와 관련 이 있 을 수도 있 고,실제 테스트 는 매우 빠르다.그리고 FastBlur 보다 빠 른 것 같 습 니 다.고 스 퍼 지 실현 방법의 성능 을 시험 해 볼 시간 이 있 으 면 비교 해 보 세 요.
여기까지 고 스 의 모호 함 을 실현 하 는 이런 방법 은 이미 모두 말 했 습 니 다.원 블 로 거들 의 이렇게 우수한 글 에 감 사 드 리 고 다시 링크 를 첨부 합 니 다.
추 수장 천 C 는 1 분 동안 동적 모호 효 과 를 실현 하 는 것 을 가르쳐 준다.
기타 참고 자료
RenderScript C Android Developers
Android RenderScript 입문(1)
가우스 퍼 지 효과 실현 방안 및 성능 대비 C lcyFox
프로젝트 원본 코드
BlurDemo C IamXiaRui C Github
이상 은 안 드 로 이 드 동적 고 스 퍼 지 효과 튜 토리 얼 에 대한 예 입 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.