android动态模糊效果(1)

本文介绍了三种实现滑动模糊效果的方法:逐像素计算、使用renderscript及opengl,并详细展示了如何在Android中利用高斯模糊算法结合JNI和renderscript实现这一效果。

由于项目类似滑动模糊的效果于是下午搜了并研究了一下滑动模糊的原理,实现滑动模糊基本有三个方案:

1.采用算法逐个像素胡算出模糊胡像素点。(这样就是帧数多了很耗CPU,不停的发热)

 2.使用android自带的renderscript渲染脚本里面的高斯模糊渲染来实现。

3.使用opengl。

目前我推断有以上三个方式现在我逐一去实现它们。

Google了一下有好几种常用的模糊算法,最常用的为高斯模糊算法。

首先写一个简单的布局


<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<com.sina.tianqitong.ui.main.PullToFreshView
android:id="@+id/pulltorefresh"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</com.sina.tianqitong.ui.main.PullToFreshView>

</merge>


得到這個scrollview的引用mScrollView,监听其触屏消息,这里主要在它收到的move事件时向handler发送了一个消息,而这个消息就是主要用来实现取得scrollview停止滑动的时机 ,然后又要监听当快速滑动手离开屏幕时Scrollview的移动位置,因为Scrollview并没有向外界提供它快速滑动手势离开时它的情况,我通过监听view树里的滑动事件来解决这个问题。

mScrollView.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					...
				}

				if (event.getAction() == MotionEvent.ACTION_MOVE
						&& mNeedUpdate == true) {
					...
					mHandler.sendEmptyMessage(MSG_UPDATE_SCROLLY);
					mNeedUpdate = false;
				}

				if (event.getAction() == MotionEvent.ACTION_UP) {
					
				}

				return false;
			}
		});
/**
	 * 用来实现判断是否Scrollview停止滑动
	 */
	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {

			if (msg.what == MSG_UPDATE_SCROLLY)
				postDelayed(new Runnable() {

					@Override
					public void run() {

						if (mLastScrollY != mScrollView.getScrollY()) {
							mLastScrollY = mScrollView.getScrollY();
							// post(this);
						} else {

							mNeedUpdate = true
							HomepageDataObserverable
									.getInstance(getContext())
									.notifyUpdate(
											HomepageDataObserverable.NOTIFITION_UPDATE_CONTENT_POSITION);
							// removeCallbacks(this);

						}

					}
				}, 100);
		}

	};


mScrollView.getViewTreeObserver().addOnScrollChangedListener(
				new OnScrollChangedListener() {

					@Override
					public void onScrollChanged() {

				if (mScrollView.getScrollY() != mRecordY) {
					mRecordY = mScrollView.getScrollY();
					mHandler.sendEmptyMessage(MSG_UPDATE_SCROLLY);
				}
				if (mScrollView.getScrollY() <= BLUR_DISTANCE
							&& mScrollView.getScrollY()% SAMPLING_FREQUENCY == 0) {

					if (mRadio != mScrollView.getScrollY()/ SAMPLING_FREQUENCY
						&& mBgCacheBitmap != null) {

					mCurrentRadio = mScrollView.getScrollY()/ SAMPLING_FREQUENCY;
					mSbManager.process(mRadio/ SAMPLING_FREQUENCY);
                                        mBlurImageView.setBackgroundDrawable(null);
					mBlurImageView.setBackgroundDrawable(new BitmapDrawable(
							mSbManager.returnBlurredImage()));

				    }
					}
				});


这里用到了一个StackBlurManager类这个是实现模糊效果的关键类,这个类是别人写好的一个提供了高斯模糊算法的类,包括使用了jni的项目和renderscript的 ,在github上相关的代码链接点击打开链接。这个项目主要就是通过分配了一个线程池然后再这个线程池里面计算像素点的方式来实现模糊效果。我实际使用发现使用jni和不使用差异不会太大,大概在10几道几十个毫秒的差异,我通过缩小了图片的分辨率来减少了计算量,因为本身我这边模糊的图片都是高清的所以减少了4倍的分辨率后对视觉上没有太大影响,4倍的分辨率就是4倍的计算量哦,所以要想减少计算模糊的时间还是图片相对得小一点,用不用本地代码实现的算法差异都不是很大








                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值