国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

教你快速實現Android動態模糊效果

2019-12-12 05:32:45
字體:
來源:轉載
供稿:網友

前言

雅虎天氣的界面上滑的時候背景圖片會跟著移動,最重要的是背景圖片會根據手指上下移動的距離來進行不同程度的模糊,感覺甚為驚奇,畢竟大家都知道,在Android平臺上進行模糊渲染是一個相當耗CPU也相當耗時的操作,一旦處理不好,卡頓是在所難免的。

一般來說,考慮到效率,渲染一張圖片最好的方法是使用OpenGL,其次是使用C++/C,使用Java代碼是最慢的。但是Android推出RenderScript之后,我們就有了新的選擇,測試表明,使用RenderScript的渲染效率和使用C/C++不相上下,但是使用RenderScript卻比使用JNI簡單地多!同時,Android團隊提供了RenderScript的支持庫,使得在低版本的Android平臺上也能使用。

不過在使用RenderScript之前,對于模糊一張圖片,需要注意的是,我們應該盡量不要使用原尺寸分辨率的圖片,最好將圖片縮小比例,這小渲染的效率要高一些。

動態模糊的實現

如何使用RenderScript來模糊一張圖片呢?廢話不多說,先上核心代碼:

public class BlurBitmap { /**  * 圖片縮放比例  */ private static final float BITMAP_SCALE = 0.4f; /**  * 最大模糊度(在0.0到25.0之間)  */ private static final float BLUR_RADIUS = 25f;  /**  * 模糊圖片的具體方法  *  * @param context 上下文對象  * @param image  需要模糊的圖片  * @return   模糊處理后的圖片  */ public static Bitmap blur(Context context, Bitmap image) {  // 計算圖片縮小后的長寬  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(BLUR_RADIUS);  // 設置blurScript對象的輸入內存  blurScript.setInput(tmpIn);  // 將輸出數據保存到輸出內存中  blurScript.forEach(tmpOut);   // 將數據填充到Allocation中  tmpOut.copyTo(outputBitmap);   return outputBitmap; }}

完成上面的代碼后,需要在app的gradle文件中添加如下的支持:

 defaultConfig { ...... renderscriptTargetApi 19 renderscriptSupportModeEnabled true}

代碼做了簡單的注釋以幫助理解,如果需要詳細了解,可以查閱官方文檔

然后,我們可以看一下模糊前和模糊后的效果對比:

將圖片模糊后,接下來要考慮的是怎么實現動態模糊效,有一點需要注意的是,即使我們使用了RenderScript這種高效的渲染方式,但是在實際測試中,渲染一張500*700分辨率的PNG格式圖片,在我的Pro 6手機上,仍然需要50ms左右的時間,顯然如果使用上面的代碼進行實時渲染的話,會造成界面嚴重的卡頓。

既然實時渲染這條路走不通,那么就需要我們另辟蹊徑了,我這里可以提供一種方法:先將圖片進行最大程度的模糊處理,再將原圖放置在模糊后的圖片上面,通過不斷改變原圖的透明度(Alpha值)來實現動態模糊效果。

簡單的代碼如下:

public class MainActivity extends AppCompatActivity {  /**  * 原始圖片控件  */ private ImageView mOriginImg;  /**  * 模糊后的圖片控件  */ private ImageView mBluredImage;  /**  * 進度條SeekBar  */ private SeekBar mSeekBar;  /**  * 顯示進度的文字  */ private TextView mProgressTv;  /**  * 透明度  */ private int mAlpha;  /**  * 原始圖片  */ private Bitmap mTempBitmap;  /**  * 模糊后的圖片  */ private Bitmap mFinalBitmap;  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);   // 初始化視圖  initViews();   // 獲取圖片  mTempBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dayu);  mFinalBitmap = BlurBitmap.blur(this, mTempBitmap);   // 填充模糊后的圖像和原圖  mBluredImage.setImageBitmap(mFinalBitmap);  mOriginImg.setImageBitmap(mTempBitmap);   // 處理seekbar滑動事件  setSeekBar(); }  /**  * 初始化視圖  */ private void initViews() {  mBluredImage = (ImageView) findViewById(R.id.activity_main_blured_img);  mOriginImg = (ImageView) findViewById(R.id.activity_main_origin_img);  mSeekBar = (SeekBar) findViewById(R.id.activity_main_seekbar);  mProgressTv = (TextView) findViewById(R.id.activity_main_progress_tv); }  /**  * 處理seekbar滑動事件  */ private void setSeekBar() {  mSeekBar.setMax(100);  mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {   @Override   public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {    mAlpha = progress;    mOriginImg.setAlpha((int) (255 - mAlpha * 2.55));    mProgressTv.setText(String.valueOf(mAlpha));   }    @Override   public void onStartTrackingTouch(SeekBar seekBar) {    }    @Override   public void onStopTrackingTouch(SeekBar seekBar) {    }  }); }}

xml布局文件代碼如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent">  <FrameLayout  android:layout_width="match_parent"  android:layout_weight="1"  android:layout_height="0dp">   <ImageView   android:id="@+id/activity_main_blured_img"   android:scaleType="centerCrop"   android:src="@drawable/dayu"   android:layout_width="match_parent"   android:layout_height="match_parent"/>   <ImageView   android:id="@+id/activity_main_origin_img"   android:scaleType="centerCrop"   android:layout_width="match_parent"   android:layout_height="match_parent"/> </FrameLayout>  <LinearLayout  android:orientation="vertical"  android:layout_width="match_parent"  android:layout_height="80dp">   <SeekBar   android:layout_marginTop="@dimen/activity_vertical_margin"   android:id="@+id/activity_main_seekbar"   android:layout_width="match_parent"   android:layout_height="wrap_content"   android:layout_marginLeft="16dp"   android:layout_marginRight="16dp"/>   <TextView   android:id="@+id/activity_main_progress_tv"   android:text="0"   android:textSize="24sp"   android:layout_gravity="center"   android:layout_width="wrap_content"   android:layout_height="wrap_content"/> </LinearLayout> </LinearLayout>

效果如下:

怎么樣?是不是很簡單的樣子?只需要調用模糊處理方法,并在SeekBar的滑動監聽里面調用原圖像的setAlpha()方法,來實現動態模糊效果。

你以為這樣就完了?不不不,我們的目的并不是這么單純,哦,不對,并不是這么簡單。還記得文章開頭的時候說了嗎?我們的終極目的是要簡單地模仿一下雅虎天氣的界面效果。

仿雅虎天氣界面

有了上面的基礎,就可以很容易地模仿雅虎天氣的界面效果。簡單來說,在上面制作出的效果基礎上,有以下兩點需要注意的地方:

需要要監聽滑動事件,然后再將背景圖片調用setTop()方法,將圖片向上平移一段距離。
要向上平移圖片,還需要手動增加圖片的高度,不然圖片向上平移后,底部就會有留白。設置圖片高度的核心代碼如下:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display display = wm.getDefaultDisplay();Point point = new Point();display.getSize(point);// 獲取到ImageView的高度int height = point.y;ViewGroup.LayoutParams params = imageView.getLayoutParams();params.width = ViewGroup.LayoutParams.MATCH_PARENT;// 將ImageView的高度增加100params.height = height + 100;// 應用更改設置imageView.requestLayout();

完成上面兩點的內容后,基本就可以模仿出雅虎天氣的首頁了。

結合第一個例子的demo,效果如下:

總結

以上就是本文的全部內容了,實現后的效果是不是很贊呢?感興趣的朋友快快自己動手操作起來吧,希望本文對大家開發Android能有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 甘南县| 咸宁市| 巩留县| 麻江县| 石城县| 太湖县| 河北区| 长沙市| 集贤县| 普兰县| 右玉县| 吉水县| 青田县| 芦溪县| 浙江省| 武鸣县| 南安市| 喀喇沁旗| 盘山县| 库尔勒市| 定州市| 汕尾市| 大同市| 平阴县| 泸溪县| 柯坪县| 桦南县| 建宁县| 繁峙县| 福州市| 舟山市| 泌阳县| 葫芦岛市| 通化市| 西宁市| 东丽区| 江安县| 宁城县| 长治县| 宁城县| 鄂尔多斯市|