首页 > 编程知识 正文

动态模糊效果怎么做,动态模糊效果app

时间:2023-05-05 23:20:09 阅读:243845 作者:2603

        现在,越来越多的App里面使用了模糊效果,尤其是动效效果中尤为常见。

        对于这类需求,Android推出RenderScript。测试表明,使用RenderScript的渲染效率和使用C/C++不相上下,但是使用RenderScript却比使用JNI简单地多!同时,Android团队提供了RenderScript的支持库,使得在低版本的Android平台上也能使用。

RenderScript实现 代码实现 /** * Created by hangli on 2018/11/27. */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; }}

       由于是Android是在api19,也就是Android4.4以后,才提供了RenderScript的支持库。因此,完成上面的代码后,还需要在app的gradle文件中添加如下的支持: 

defaultConfig { ...... renderscriptTargetApi 19 renderscriptSupportModeEnabled true} 对比结果

       将图片模糊后,接下来要考虑的是怎么实现动态模糊效,有一点需要注意的是,即使我们使用了RenderScript这种高效的渲染方式,对于手机的性能有一定的要求,严重时会造成界面严重的卡顿。

        因此,我在网上找到另一种方法:先将图片进行最大程度的模糊处理,再将原图放置在模糊后的图片上面,通过不断改变原图的透明度(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.mipmap.test); 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 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="@mipmap/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="20dp" 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>

 

动态效果 

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。