Android 동적 가우스 퍼 지 효과 구현
가우스 퍼 지(영어:Gaussian Blur)는 가우스 평활 이 라 고도 부 르 는데 Adobe Photoshop,GIMP,Paint.NET 등 이미지 처리 소프트웨어 에서 광범 위 하 게 사용 되 는 처리 효과 로 이미지 소음 을 줄 이 고 디 테 일 한 차원 을 낮 춘 다.이런 모호 한 기술 로 생 성 된 이미 지 는 그 시각 적 효 과 는 반투명 스크린 을 통 해 이미 지 를 관찰 하 는 것 과 같다.이것 은 렌즈 의 초점 외 영상 효과 와 산 경,그리고 일반 조명 그림자 에서 의 효과 와 현저히 다르다.
뭐?잘 안 보 여?괜찮아,나 도 잘 모 르 겠 어.위 키 피 디 아 에서 복 사 했 잖 아.우 리 는 직접 그림 을 넣 어서 이 고 스 의 모호 함 이 어떤 지 알 아 보 았 다.가우스 모호 함 은 iOS 에서 가장 흔히 볼 수 있 기 때문에 iOS 왕 이 운 의 사진 몇 장 을 잡 았 다.
이 인터페이스의 배경 을 볼 수 있다.사실은 그림 1 중간 에 있 는 작은 그림 을 통 해 모호 하 게 얻 은 것 이다.이렇게 하 는 장점 은 전체 성 이 좋 고 그림 의 과도 가 갑 작 스 러 워 서 화면 내용 의 읽 기 에 영향 을 주지 않 는 다 는 것 이다.
과연 안 드 로 이 드 에 서 는 어떻게 이 효 과 를 이 룰 수 있 을 까?Support Library 에 공식 적 으로 제공 되 는 도 구 를 사용 하 는 것 을 추천 합 니 다.바로 RenderScript 입 니 다.이 RenderScript 의 기능 은 사실 이것 뿐만 아니 라 다른 기능 도 있 습 니 다.공식 문서 에서 읽 고 공부 할 수 있 습 니 다.여 기 는 제시 하지 않 습 니 다.
이 도 구 를 사용 하 는 이 유 는 사실 매우 간단 하 다.바로 성능 이다.그림 그리 기 와 관련 되 어 있 기 때문에 성능 이 좋 지 않 으 면 고 품질 그림 이나 변화 가 많은 수요 에 도 불구 하고 이 도 구 는 장치 의 컴 퓨 팅 능력(CPU 와 GPU)을 충분히 발휘 하여 계산 하고 C99 파생 언어 인 행각 본 을 사용 하여 작 성 된 것 으로 자바 에 비해 성능 이 크게 향상 되 었 습 니 다.
여기까지 말 하 자 어떤 학우 들 은 시작 했다.C99 파생?What?이 는 걱정 할 필요 가 없습니다.가우스 의 모호 함 에 대해 Google 은 공식 적 으로 해결 방안 을 제 시 했 습 니 다.저 희 는 해당 하 는 스 크 립 트 를 작성 하지 않 아 도 사용 할 수 있 기 때문에 걱정 할 필요 가 없습니다.
우 리 는 전체 문 제 를 두 부분 으로 나 누 었 다.
① 가우스 모호 실현;
② 동적 고 스 모호 실현
① 가우스 모호 실현
우선 Support Library 를 사용 해 야 하기 때문에 버 전 은 다음 과 같은 요구 가 있 습 니 다.
Android SDK Tools 버 전 은 22.2 이상 이 어야 합 니 다.
Android SDK Build-tools 버 전 은 18.1.0 이상 이 어야 합 니 다.
만약 도달 하지 못 했다 면 SDK Manager 를 사용 하여 업 그 레이 드 를 하 세 요.
이어서 프로젝트 를 만 들 고 모듈(기본적으로 app)에 대응 하 는 build.gradle 파일 에 다음 코드 를 추가 합 니 다.
defaultConfig {
...
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
}
renderscriptTargetApi:이것 은 일반적으로 앱 이 지원 하 는 최저 버 전과 같 으 면 됩 니 다.
package com.fndroid.renderscriptdemo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView mImageView;
private Bitmap sampleImg;
private Bitmap gaussianBlurImg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.iv);
sampleImg = BitmapFactory.decodeResource(getResources(), R.drawable.icon); //
gaussianBlurImg = blur(sampleImg, 25f);
mImageView.setImageBitmap(gaussianBlurImg);
}
private Bitmap blur(Bitmap bitmap,float radius) {
Bitmap output = Bitmap.createBitmap(bitmap); //
RenderScript rs = RenderScript.create(this); // RenderScript
ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
Allocation allIn = Allocation.createFromBitmap(rs, bitmap); //
Allocation allOut = Allocation.createFromBitmap(rs, output); //
gaussianBlue.setRadius(radius); // , 0f<radius<=25f
gaussianBlue.setInput(allIn); //
gaussianBlue.forEach(allOut); // ,
allOut.copyTo(output); // Bitmap,
rs.destroy(); // RenderScript ,API>=23 rs.releaseAllContexts()
return output;
}
}
코드 에 주석 이 달 려 있 습 니 다.알 아야 할 것 은 RenderScript 에 두 가지 버 전이 있 는데 그것 이 바로:android.renderscript
android.support.v8.renderscript
위의 코드 는 첫 번 째,두 번 째 용법 이 유사 하여 스스로 시도 할 수 있다.
렌 더 스 크 립 트 는 Script 에 의존 하기 때문에 상기 에서 도 말 했 듯 이 Script 는 C99 파생 언어 로 작 성 된 것 이 고 코드 중의 ScriptIntrinsicBlur 는 고 스 퍼 지 알고리즘 에 대응 하 는 스 크 립 트 입 니 다.알 로 케 이 션 대상 은 자바 의 대상 을 Script 스 크 립 트 로 변환 하 는 데 필요 한 유형의 도 우미 입 니 다.코드 에 두 개의 알 로 케 이 션 대상 을 각각 입력 과 출력 으로 만 들 었 습 니 다.이 어 고 스 의 모호 한 반경(radius)을 설치 했다.foreach 를 호출 할 때 스 크 립 트 가 실 행 됩 니 다.출력 에 대응 하 는 Allocation 에 실행 결 과 를 입력 하고 마지막 으로 copyTo 를 호출 하여 Bitmap 대상 으로 되 돌려 줍 니 다.
효과 그림:
② 동적 가우스 모호
모호 한 정도 로 그림 이 필요 할 때 가 많다.당신 은 위의 방법 중의 모호 한 반지름 을 이미 알 고 있 을 것 입 니 다.우 리 는 하나의 실험 을 할 수 있 습 니 다.바로 SeekBar 를 통 해 이 값 을 동태 적 으로 바 꾸 어 효 과 를 볼 수 있 습 니 다.
움 직 이 는 그림 에서 볼 수 있 듯 이 우리 가 SeekBar 를 끌 었 을 때 SeekBar 는 이미 우리 의 드래그 를 따라 가지 못 했다.왜 이래?그 이 유 는 이 렌 더 링 도 구 는 성능 이 비교적 우수 하지만 그림 의 질과 사이즈 가 모두 높 을 때 우 리 는 모호 한 반지름 을 직접 수정 하여 다시 렌 더 링 하 는 방법 은 바람 직 하지 않다 는 것 이다.
방법 은 먼저 이미지 뷰 에 흐릿 한 그림 을 만 들 고 이 이미지 뷰 위 에 원본 이미지 뷰 를 불 러 옵 니 다.FrameLayout 를 사용 하면 두 이미지 뷰 를 겹 쳐 서 함께 할 수 있 습 니 다.이 어 우리 가 모호 한 정 도 를 동적 으로 바 꿔 야 할 때 상층 의 이미지 뷰 의 BitmapAlpha 를 바 꾸 면 됩 니 다.우리 먼저 효과 도 를 보 자.
이 방법 을 사용 하면 미 끄 러 지면 비교적 유창 해진 다.GIF 로드 가 완료 되 어야 정상 속도 입 니 다)
여기 코드 참고 좀 해 주세요.
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
private ImageView mImageView;
private ImageView mImageViewCover;
private Bitmap sampleImg;
private Bitmap gaussianBlurImg;
private SeekBar mSeekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.iv);
mSeekBar = (SeekBar) findViewById(R.id.sb);
mImageViewCover = (ImageView) findViewById(R.id.iv_cover);
sampleImg = BitmapFactory.decodeResource(getResources(), R.drawable.icon); //
gaussianBlurImg = blur(sampleImg, 25f);
mImageView.setImageBitmap(gaussianBlurImg);
mSeekBar.setOnSeekBarChangeListener(this);
}
private Bitmap blur(Bitmap bitmap, float radius) {
Bitmap output = Bitmap.createBitmap(bitmap); //
RenderScript rs = RenderScript.create(this); // RenderScript
ScriptIntrinsicBlur gaussianBlue = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); //
//
Allocation allIn = Allocation.createFromBitmap(rs, bitmap); //
Allocation allOut = Allocation.createFromBitmap(rs, output); //
gaussianBlue.setRadius(radius); // , 0f<radius<=25f
gaussianBlue.setInput(allIn); //
gaussianBlue.forEach(allOut); // ,
allOut.copyTo(output); // Bitmap,
rs.destroy(); // RenderScript ,API>=23 rs.releaseAllContexts()
return output;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int alpha = 255 - progress;
mImageViewCover.setImageAlpha(alpha);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
레이아웃 파일:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.fndroid.renderscriptdemo.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/iv_cover"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/icon"/>
</FrameLayout>
<SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="255"/>
</LinearLayout>
총결산이상 은 안 드 로 이 드 에서 동태 적 인 고 스 모호 함 을 실현 하 는 모든 내용 입 니 다.본 고 는 먼저 고 스 모호 함 을 어떻게 실현 하 는 지 소개 한 다음 에 동태 적 인 효 과 를 실현 하 는 것 을 소개 합 니 다.그러면 여러분 들 이 학습 을 쉽게 이해 할 수 있 고 본 고 는 여러분 들 이 안 드 로 이 드 를 개발 하 는 데 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.