`
yaolinnan
  • 浏览: 58593 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

【转载】一种快速毛玻璃虚化效果实现

 
阅读更多

原文:http://www.androidchina.net/4626.html

 

在iOS设备上我们随处可见毛玻璃效果,而且最近越来越多的场合应用到了这种美观的虚化效果,包括本人的一个开源项目BlureImageView也是受此启发。所以,恰到好处的虚化效果能很好的改善用户体验,而且也能让你的app显得更加优雅。

不过,我们目前在android上很少见到毛玻璃效果,我认为很重要的原因是性能问题,虚化一张图片所需要的时间会因设备而异,如果为了虚化使得用户需要刻意等待,那么就是弊大于利。另外,Google官方提供的renderScript一般只是做一些小幅度的虚化,很难达到毛玻璃这类深度虚化效果。

所以本文的角度是能够在android设备上快速实现毛玻璃效果。

blob.png

blob.png

StackBlur

首先,为了实现毛玻璃效果,本文采用的是StackBlur模糊算法,这种算法应用非常广泛,能得到非常良好的毛玻璃效果。在这里,我们使用的是它的Java实现代码FastBlur.java

public static Bitmap doBlur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap)

 

可以看出,使用方法非常简单,传入待虚化的bitmap、虚化程序(一般为8)、和是否重用flag。

然后,如果要对上面这张图片进行虚化,我们可以通过把它转化成bitmap传入虚化,看起来很简单就解决了,但事实并非如此。

OOM

如果直接把一张大图传入,很容易就会发生OOM内存溢出

03-11 21:02:02.014 16727-16742/com.wingjay.jayandroid I/art: Clamp target GC heap from 109MB to 96MB
03-11 21:02:02.026 16727-16727/com.wingjay.jayandroid I/art: Clamp target GC heap from 109MB to 96MB
03-11 21:02:02.030 16727-16727/com.wingjay.jayandroid I/art: Clamp target GC heap from 109MB to 96MB
03-11 21:02:02.031 16727-16727/com.wingjay.jayandroid I/art: Forcing collection of SoftReferences for 30MB allocation
03-11 21:02:02.035 16727-16727/com.wingjay.jayandroid I/art: Clamp target GC heap from 109MB to 96MB
03-11 21:02:02.036 16727-16727/com.wingjay.jayandroid E/art: Throwing OutOfMemoryError "Failed to allocate a 32175012 byte allocation with 2648672 free bytes and 2MB until OOM"
03-11 21:02:02.036 16727-16727/com.wingjay.jayandroid D/AndroidRuntime: Shutting down VM

 

这是我直接对原图进行虚化得到的log信息。可以看出当虚化开始时,虚拟机开始不断进行内存回收,包括把所有软引用的内存回收。然而,仍然导致了内存溢出。

那就意味着我只能虚化小图,这样才能防止内存溢出。但是我并不想换其他图,那么,我们就应该把这张图缩放。

ReScale

 
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) {}

我们可以利用这个function来进行bitmap的缩放。其中前三个参数很明显,其中宽高我们可以选择为原图尺寸的1/10;第四个filter是指缩放的效果,filter为true则会得到一个边缘平滑的bitmap,反之,则会得到边缘锯齿、pixelrelated的bitmap。这里我们要对缩放的图片进行虚化,所以无所谓边缘效果,filter=false。

所以,我们要使用

int scaleRatio = 10;
int blurRadius = 8;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
     originBitmap.getWidth() / scaleRatio,
     originBitmap.getHeight() / scaleRatio,
     false);
Bitmap blurBitmap = FastBlur.doBlur(scaledBitmap, blurRadius, true);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(blurBitmap);

 

可以得到如下效果:

blob.png

blob.png

从图中可以看出,首先可以确定思路是对的;然后,可以看出毛玻璃效果还不是特别的明显。为了得到如iOS那样的虚化效果,我们有两种方法:

  • 增大scaleRatio缩放比,使用一样更小的bitmap去虚化可以得到更好的模糊效果,而且有利于占用内存的减小;
  • 增大blurRadius,可以得到更高程度的虚化,不过会导致CPU更加intensive

这里本人通过增大缩放比来实验。

  • scaleRatio = 20
  • scaleRatio = 35
  • scaleRatio = 50
  • scaleRatio = 100
    scaleRatio_100

通过上面对比图我们可以找出最适合自己的虚化效果。

Performance analysis

那么,要实现这样的效果,是否具有损害用户体验的风险呢?下面,我们从消耗时间和占据内存的角度来进行分析。

Time Consuming

为了分析虚化一张图片所消耗的时间,本文通过同时虚化100来获取平均消耗时间。以期对虚化耗时和不同缩放比对耗时的影响得到一定的认识。

long start = System.currentTimeMillis();
Bitmap scaledBitmap, blurBitmap;
int scaleRatio = 10;
int loopCount = 100
for (int i=0; i<loopCount; i++) {
    scaledBitmap = Bitmap.createScaledBitmap(originBitmap,
    originBitmap.getWidth() / scaleRatio,
    originBitmap.getHeight() / scaleRatio,
    false);
    blurBitmap = FastBlur.doBlur(scaledBitmap, 8, true);
}
Log.i("blurtime", String.valueOf(System.currentTimeMillis() - start));

 
  • scaleRatio = 10: 耗时887ms,平均耗时8.87ms;
  • scaleRatio = 20: 耗时224ms,平均耗时2.24ms;
  • scaleRatio = 35: 耗时99ms,平均耗时0.99ms;
  • scaleRatio = 50: 耗时55ms,平均耗时0.55ms;
  • scaleRatio = 100: 耗时29ms,平均耗时0.29ms;

为了方便读者了解效果,我通过多组数据拟合了下面的曲线:

blob.png

从该模拟图可以看出时间随着缩放比的增大而不断减小,当缩放比达到30以上时所消耗的时间不到1ms,因此,我认为应该是完全不会产生时延破坏用户体验的。

Memory Consuming

既然时间没问题,那么,主要问题:内存占用就来了,所以我们需要考察生成一张虚化图片所占用的内存。

为了测试对一张图片进行虚化所占用内存的变化,我们改变虚化次数,即修改上面的loopCount并观察对内存的变化。其中scaleRatio = 10,以获得相对较大的内存消耗。

  • loopCount = 1
  • loopCount = 10
  • loopCount = 20
  • loopCount = 50
  • loopCount = 100
  • loopCount = 300

从上面的内存消耗图,可以看出虚化的确会占用一定内存,如果大量的虚化同时发生,则会由于UI线程突然加载很多bitmap而导致内存抖动。

Conclusion

希望大家如果有其他测试方法或者意见多多留言,从而继续改进性能。

附上本文所采用的

测试图

谢谢!

分享到:
评论

相关推荐

    MFC实现的窗体毛玻璃效果

    MFC实现的窗体毛玻璃效果。 实现的方法主要是使用以下函数: DwmExtendFrameIntoClientArea(...) 该函数实现将边框区域扩大到客户区,而此时边框区域的绘制,在windows vista和windows 7系统下在开启了毛玻璃效果...

    MFC下实现毛玻璃效果

    想在Win7下重画MFC应用程序界面及实现界面的毛玻璃效果,在网上溜达一下发现“用C++品尝Vista美味:界面地毛玻璃效果”,各大网站都是相互转载的同一篇文章。这篇文章是基于WTL实现的,其中有个默认主题句柄。而MFC...

    窗口毛玻璃效果(c++源码加程序)

    标题中的“窗口毛玻璃效果(c++源码加程序)”指的是使用C++编程语言实现的一种视觉效果,这种效果通常被称作“模糊效果”或“毛玻璃效果”。在现代操作系统如Windows 10中,这种效果常用于窗口背景,使得窗口下方的...

    QT C++ 实现毛玻璃窗口,透明+模糊效果

    在本文中,我们将深入探讨如何使用QT C++库来实现毛玻璃效果,即窗口的透明度与模糊结合的视觉效果。这种技术常用于现代UI设计,以提供更优雅、时尚的用户界面。我们将通过分析“glassui”这个压缩包中的源代码来...

    Android 局部毛玻璃透明效果

    在Android开发中,为了提升应用的视觉效果和用户体验,开发者经常使用各种特效,其中“局部毛玻璃透明效果”就是一种流行的设计风格。这种效果模仿了iOS中的“Blurry”技术,使得界面的一部分呈现出模糊透明的效果,...

    Qt qml 实现毛玻璃效果

    毛玻璃效果,也被称为模糊效果或亚克力效果,是现代用户界面设计中的一种流行元素,它能为应用程序提供一种半透明且模糊的背景,使用户界面更具吸引力和深度感。 首先,`main.cpp`是Qt应用的入口点,通常会包含初始...

    HTML毛玻璃效果代码

    HTML毛玻璃效果是一种流行的设计趋势,它模仿了iOS 7及更高版本中引入的模糊背景效果,也称为“Blur Effect”或“Dynamic Blur”。这种效果可以让背景内容在不影响主要元素可读性的同时,呈现出朦胧而美观的视觉感受...

    Wpf 毛玻璃效果实现

    Wpf毛玻璃效果实现.亲测可用. 本资源来自http://download.csdn.net/download/fengchun_doff/8006205 直接编译无法通过.移除了相关引用. 可以直接使用.因为是转的,最少积分共享给大家.

    Android 毛玻璃效果完美实现

    在Android平台上,毛玻璃效果(通常称为模糊效果或Blur Effect)是一种流行的设计趋势,它可以为应用界面增添一种高级感和深度。iOS系统自iOS7开始引入了这种效果,但随着Android设计语言的发展,Android也开始支持...

    Android模糊处理简单实现毛玻璃效果

    自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果、磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片: 实现效果大家都知道了,如何在Android中实现呢,说白了...

    Qt Windows下的毛玻璃效果

    毛玻璃效果,也称为模糊效果,常用于现代用户界面设计中,为用户提供一种优雅、时尚的视觉体验。 首先,让我们了解如何实现半透明效果。在Qt中,可以通过设置窗口的`Qt::WA_TranslucentBackground`属性来实现这一...

    毛玻璃效果(demo)

    在Android平台上实现毛玻璃效果,通常涉及到以下知识点: 1. **渲染引擎**:Android的渲染引擎是负责将UI组件和图像绘制到屏幕上的关键部分。毛玻璃效果的实现往往需要与渲染引擎交互,调整图像的模糊程度和透明度...

    unity CommandBuffer 实现毛玻璃效果

    unity command buffer 实现毛玻璃特效,可用于3D物体或UI。

    MFC实现毛玻璃效果

    在Windows 7操作系统中,微软引入了一种名为“Aero”的视觉风格,其中最具特色的就是“毛玻璃”(Aero Glass)效果。毛玻璃效果通过半透明的、模糊的背景,为用户界面带来了轻盈和现代感。在MFC(Microsoft ...

    QT C++ QWidget 自定义头窗口头标+毛玻璃效果

    本教程将探讨如何利用`QWidget`自定义一个带有独特头部设计和毛玻璃效果的窗口。毛玻璃效果,又称模糊效果,能为窗口提供半透明、朦胧的视觉体验,使界面更具现代感和美观度。 首先,我们需要理解`QWidget`的基本...

    Unity毛玻璃模糊效果Shader

    Unity毛玻璃模糊效果Shader,直接赋值到材质球上进行使用即可。

    BlurTest(毛玻璃效果的实现)

    毛玻璃效果,也被称为模糊效果或者视觉模糊,是一种在用户界面设计中常用的设计元素,它通过部分模糊背景图像来突出前景元素,增加视觉层次感,同时也能为用户提供更好的交互体验。在iOS、Android以及Web开发中,都...

    QML在WIN10上实现毛玻璃效果.rar

    在Windows 10系统中,我们可以利用QML来实现“毛玻璃”(又称为模糊或Acrylic Effect)效果,这种效果为用户界面带来了一种现代且时尚的视觉体验。本文将详细讲解如何在QML中实现在Windows 10上的毛玻璃效果。 首先...

    android毛玻璃效果

    在Android平台上,毛玻璃效果,也被称为模糊效果,是一种流行的设计趋势,它使得背景元素呈现出半透明且模糊的视觉效果,常用于对话框、卡片视图等组件,以增加界面的深度和层次感。本教程将详细介绍如何在Android...

    wpf 实时毛玻璃 live blur 效果

    在Windows Presentation Foundation (WPF) 中,实时毛玻璃(Live Blur)效果是一种视觉设计技术,它使得背景元素呈现出模糊的效果,常用于创建现代、透明且交互性强的用户界面。这种效果在Windows 8及更高版本的UI...

Global site tag (gtag.js) - Google Analytics