仿有道云笔记头像背景

泡在网上的日子 / 文 发表于2015-03-04 20:21 次阅读 云笔记

转自 仿有道云笔记头像背景 

前言

如题,本文模仿实现有道云笔记的侧滑菜单中的头像背景的效果,这一效果可用借鉴使用,毕竟大多数时候我们在应用上的资料可能没有像play、微博等的个人页面的自定义背景图。没用过这款应用的童鞋可以下载这款应用看看。

分析

先来看看有道云笔记上的图片(重点是头像上的背景图,真机看起来效果比较好):
有道云笔记效果图

有道云笔记效果图

在手机上没找到背景的效果图,应该是在手机上生成的效果图,根据它的背景图片可以看出图片时黑白的而且是有点朦胧感,所以经过分析和实验得到做这一效果可以使用的方法:黑白效果用ColorFilter实现、模糊效果可以用RenderScript的API实现。代码的步骤也是先得到黑白的Bitmap再把它模糊处理。

黑白

Android中图片是以RGBA像素点的形式加载到内存中的,这些像素信息通过ColorMatrix,官方文档的描述如下:
4×5矩阵转换位图的颜色+ alpha分量。该矩阵存储在一个单独的阵列中,其进行如下处理:

[ a, b, c, d, e,
f, g, h, i, j,
k, l, m, n, o,
p, q, r, s, t ]

当应用于ColorR,G,B,A,所以将上面矩阵跟图片的原值相乘后的结果:

R' = a*R + b*G + c*B + d*A + e;
G' = f*R + g*G + h*B + i*A + j;
B' = k*R + l*G + m*B + n*A + o;
A' = p*R + q*G + r*B + s*A + t;

所以ColorMatrix经ColorFilter就可以在Android中处理图片的颜色,关于这两个类更详尽的信息可以自己继续Google一下。而把图片变黑白就简单一些了,直接通过ColorMatrix的setSaturation)方法更改图片的饱和度即可,我们知道当图片的饱和度为0时就会变为黑白了。此外我们也可麻烦一点自己通过ColorMatrix调出一个合适的值也可以,这也是ColorMatrix的强大之处,下面是黑白效果的ColorMatrix的值:

float[] src = new float[]{
    0.28F, 0.60F, 0.40F, 0, 0,
    0.28F, 0.60F, 0.40F, 0, 0,
    0.28F, 0.60F, 0.40F, 0, 0,
    0, 0, 0, 1, 0,
};

所以黑白部分的处理代码:

Drawable drawable = getResources().getDrawable(R.drawable.rocko);
Bitmap srcBitmap = BitmapUtils.drawable2Bitmap(drawable);
/*先黑白图片*/
float[] src = new float[]
{
    0.28F, 0.60F, 0.40F, 0, 0,
    0.28F, 0.60F, 0.40F, 0, 0,
    0.28F, 0.60F, 0.40F, 0, 0,
    0, 0, 0, 1, 0,
};
ColorMatrix cm = new ColorMatrix(src);
// cm.setSaturation(0.0f);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
Bitmap resultBitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(b);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setAlpha(100);
paint.setColorFilter(f);
canvas.drawBitmap(srcBitmap, 0, 0, paint);


模糊

模糊的效果处理可以有几种方式:Java、jni、Android的RenderScript API,Java代码的一种比较快的一种模糊算法实现fastBlur效果不太理想,还是比RenderScript慢些,所以最终采用Android官方的API实现RenderScript support v8的支持包,Android support v8支持包是在...\build-tools\21.1.2\renderscriptSDK的这里的,在Android Studio中使用support v8:在build.gradle的defaultConfig中加上下面两句即可,

renderscriptTargetApi 21
renderscriptSupportModeEnabled true

所以模糊部分的处理:

/*后模糊图片*/
Bitmap bB = BitmapUtils.blurBitmap(getApplicationContext(), resultBitmap, 15.5f);
//RenderScript模糊处理的使用,主要就是Allocation 、ScriptIntrinsicBlur、RenderScript这几个类,RenderScript里基本上是jni的本地代码了,不再展开
public static Bitmap blurBitmap(Context applicationContext, Bitmap bitmap, float radius)
{
    //Let's create an empty bitmap with the same size of the bitmap we want to blur
    Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    //Instantiate a new Renderscript
    RenderScript rs = RenderScript.create(applicationContext);
    //Create an Intrinsic Blur Script using the Renderscript
    ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
    //Create the Allocations (in/out) with the Renderscript and the in/out bitmaps
    Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
    Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
    //Set the radius of the blur
    blurScript.setRadius(radius);
    //Perform the Renderscript
    blurScript.setInput(allIn);
    blurScript.forEach(allOut);
    //Copy the final bitmap created by the out Allocation to the outBitmap
    allOut.copyTo(outBitmap);
    //recycle the original bitmap
    bitmap.recycle();
    //After finishing everything, we destroy the Renderscript.
    rs.destroy();
    return outBitmap;
}

工作完成,最后要注意的是模糊效果的处理是比较耗时的(~250ms),所以在UI线程里直接处理的话肯定会掉帧,16ms是界限值,建议开线程预先处理好再设置。仿照的效果图如下:
仿照效果图

仿照效果图

End

本文demo地址


收藏 赞 (2) 踩 (0)
上一篇:使用Palette类提取图片的颜色信息
原文: http://qichaochen.github.io/2014/11/16/105-Android-5.0-Palette-01/ 在Material Design设计中很重要的一部分内容是应用中图片颜色和文字颜色需要和主题相匹配,比如下面在这个应用: 文本的颜色根据不同图片动态进行对应适配(也许你会说,如果全
下一篇:Spans,一个强大的概念
转自 Spans,一个强大的概念 这篇文章的英文原文早已出现,但是文章实在是太长了,再加上这东西并不常用,所以一直没出现译文。没想到作者zhengxiaopeng居然硬是翻译出来了。。。 前言 原文: Spans, a Powerful Concept. 最近,我写了一篇关于NewStand app