使用硬件层来实现灰度视图

泡在网上的日子 / 文 发表于2015-10-31 02:37 次阅读 灰度,硬件层

最近从设计团队那里得到一个需求,让一个特定的view在彩色和灰度之间切换。灰度,一个专用术语,意思是去掉一张图片中的所有饱和度。我快速Google 了一下得到了如下的代码:

public Bitmap toGrayscale(Bitmap original) {        
    int height = original.getHeight();
    int width = original.getWidth();    

    Bitmap grayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(grayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0); // <-- important line here
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);
    c.drawBitmap(original, 0, 0, paint);
    return grayscale;
}

如果你要做的就是去掉一张图片的饱和度非常简单,但是假如我们是想去掉一个view (如果是个ViewGroup还包括所有子view)的饱和度呢?

其实一样很简单,可以通过在一个View layer上应用颜色过滤来完成。

如果我们查看LAYER_TYPE_HARDWARE(或者LAYER_TYPE_SOFTWARE)的文档,可以看到如下的解释:

"A hardware layer is useful to apply a specific color filter and/or blending mode and/or translucency to a view and all its children."

“一个hardware layer对于在view及其子view上应用颜色过滤,混合模式,半透明很有用 ”

Nice!我们可以用下面的代码来应用我们的ColorMatrixColorFilter:

public void setGreyscale(View v, boolean greyscale) {
    if (greyscale) {
        // Create a paint object with 0 saturation (black and white)
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        Paint greyscalePaint = new Paint();
        greyscalePaint.setColorFilter(new ColorMatrixColorFilter(cm));
        // Create a hardware layer with the greyscale paint
        v.setLayerType(LAYER_TYPE_HARDWARE, greyscalePaint);
    } else {
        // Remove the hardware layer
        v.setLayerType(LAYER_TYPE_NONE, null);
    }
}

这里是 Cheesesquare app变成灰度模式的gif效果:

附加提示:hardware layer非常昂贵!最好只是暂时激活一个hardware layer。

英文原文:Greyscale Views on Android 


收藏 赞 (2) 踩 (0)
上一篇:Activity管理Fragment解析
本文出自Lusfold的博客: Activity管理Fragment解析 首先Fragment的生命周期完全由所属的Activity掌控,并没有像Activity一样由AMS管理。 FragmentActivity生命周期与事件分发 先从一张图简单看下各个类之间的关系(这里并没有详细列出所有类以及类的方法,
下一篇:Android Socket 发送广播包的那些坑
Socket广播包经常被用于局域网内的两台设备之间互相发现和消息传递,在Android应用开发过程中,也经常会遇到这样的需求,例如:两台Android设备之间、Android与手环等智能硬件之间、Android与Windows电脑之间等等。 本文主要介绍在Android中使用Socket开发广