android5.0L版本新特性:主色提取

上一次周例会上,有关专家介绍了一下android5.0的一些新特性。其中一个是主色提取,按照产品经理的意思,下一期需求上我们最好能加上这个特性。于是乎,我们就开始研究一下这个新特性了。这个是放在support包里面的新增接口,也就是说这个接口和android版本无关。看来源码也不会太大。:-)

先看一下google官方说明。https://developer.android.com/reference/android/support/v7/graphics/Palette.html从这个介绍页面,我们大致能够明白:这个新增接口比较简单。一个主要构造方法,传一个bitmap对象,剩下的就是get系列方法。另外,为了方便使用,google还特意新增加了一个异步的构造方法,类似imageloader。不过这里友情提醒一下,以下几个方法,返回值有可能是空,所以使用前要做一次参数有效性判断。

    /**
     * Returns the most vibrant swatch in the palette. Might be null.
     */
    public Swatch getVibrantSwatch() {
        return mVibrantSwatch;
    }

    /**
     * Returns a light and vibrant swatch from the palette. Might be null.
     */
    public Swatch getLightVibrantSwatch() {
        return mLightVibrantSwatch;
    }

    /**
     * Returns a dark and vibrant swatch from the palette. Might be null.
     */
    public Swatch getDarkVibrantSwatch() {
        return mDarkVibrantSwatch;
    }

    /**
     * Returns a muted swatch from the palette. Might be null.
     */
    public Swatch getMutedSwatch() {
        return mMutedSwatch;
    }

    /**
     * Returns a muted and light swatch from the palette. Might be null.
     */
    public Swatch getLightMutedSwatch() {
        return mLightMutedColor;
    }

    /**
     * Returns a muted and dark swatch from the palette. Might be null.
     */
    public Swatch getDarkMutedSwatch() {
        return mDarkMutedSwatch;
    }

按理,这么好的接口,应该能够很快上手。可是在demo里发现,好多情况下,这个接口并没有取到我们想要的,也就是我们认为这附图片上最多的颜色。比如一张一眼看上去灰白占主要的图片,返回来的确是红色,或者黄色。从图片上取到的颜色,不再正常的理解范围之内。看来得研究一下源码了。

同这个特性开放的接口一样,这个特性的实现源码也不是太复杂。package android.support.v7.graphics下面总共只有四个文件,其中一个是public class。其余的三个类中,有两个class是能力层代码。具体如下:

Palette.java 对外接口类。提供一些方法的获取,以及Swatch的定义。

ColorUtils.java 业务强相关的工具类。里面都是一些静态方法。

ColorHistogram.java 实现了颜色提取算法的能力类。

ColorCutQuantizer.java 夹在ColorHistogram.java和Palette.java中间的一个封装类。不过这个类里面提供了一套颜色分裂算法。

这里我们先看一下ColorHistogram这个类是怎么实现主色提取的。构造方法里面传了一个像素点颜色值的数组。传入之后,对所有颜色值进行一次排序。在countDistinctColors方法里面给出了颜色的种类,在countFrequencies方法里面给出了每种颜色所占的比例/个数。这个算法很常见,第一次遇到的同学结合google的注释看起来也挺快的。

    private static int countDistinctColors(final int[] pixels) {
        if (pixels.length < 2) {
            // If we have less than 2 pixels we can stop here
            return pixels.length;
        }

        // If we have at least 2 pixels, we have a minimum of 1 color...
        int colorCount = 1;
        int currentColor = pixels[0];

        // Now iterate from the second pixel to the end, counting distinct colors
        for (int i = 1; i < pixels.length; i++) {
            // If we encounter a new color, increase the population
            if (pixels[i] != currentColor) {
                currentColor = pixels[i];
                colorCount++;
            }
        }

        return colorCount;
    }

    private void countFrequencies(final int[] pixels) {
        if (pixels.length == 0) {
            return;
        }

        int currentColorIndex = 0;
        int currentColor = pixels[0];

        mColors[currentColorIndex] = currentColor;
        mColorCounts[currentColorIndex] = 1;

        if (pixels.length == 1) {
            // If we only have one pixel, we can stop here
            return;
        }

        // Now iterate from the second pixel to the end, population distinct colors
        for (int i = 1; i < pixels.length; i++) {
            if (pixels[i] == currentColor) {
                // We've hit the same color as before, increase population
                mColorCounts[currentColorIndex]++;
            } else {
                // We've hit a new color, increase index
                currentColor = pixels[i];

                currentColorIndex++;
                mColors[currentColorIndex] = currentColor;
                mColorCounts[currentColorIndex] = 1;
            }
        }
    }

到这里一切都是正常。该提取的颜色应该都提取出来了。那只能接着向上看。ColorHistogram构造的结果,做为参数直接丢给了ColorCutQuantizer的构造方法。在这个构造方法里面我们找到了原因:

        // Now go through all of the colors and keep those which we do not want to ignore
        mColors = new int[rawColorCount];
        int validColorCount = 0;
        for (int color : rawColors) {
            if (!shouldIgnoreColor(color)) {
                mColors[validColorCount++] = color;
            }
        }

google按照某个标准,进行了一次颜色筛选。也就是说我们直接用接口拿到的结果,是经过某个特定的业务筛选出来的。如果我们不知道这个业务,我们拿到的颜色当然就不是我们需要的颜色。将这个筛选逻辑去掉之后,拿到的主色,也就是我们需要的,图片里面最多的颜色。

另外从google的官方说明来看,这个接口的速度非常快。在下面这个方法里面,google将图片的大小统一压缩成一个较小的图片,这个应该是处理时间快的一个重要原因:

    public static Palette generate(Bitmap bitmap, int numColors) {
        checkBitmapParam(bitmap);
        checkNumberColorsParam(numColors);

        // First we'll scale down the bitmap so it's shortest dimension is 100px
        final Bitmap scaledBitmap = scaleBitmapDown(bitmap);

个人觉得接口层还是提供能力比较好。如果这个接口层提供两套接口:1.单单的主色提取能力,2.某套颜色提取算法。这样APP在业务层里面用起来可能会更方便一些。

时间: 2024-10-12 15:14:43

android5.0L版本新特性:主色提取的相关文章

Atitit.jquery 版本新特性attilax总结

Atitit.jquery 版本新特性attilax总结 1. Jq1.4 1 2. 1.5 1 3. 1.6 3 4. Jq1.7 3 ⒉提升了事件委派时的性能有了大幅度的提升,尤其是在ie7下: 4 ⒊更好的在 ie 6/7/8 上支持 html5: 4 ⒋切换动画更加直观: 4 ⒌匿名模块定义 awd 4 ⒍jQuery.Deferred 4 ⒎jQuery.isNumeric() 4 5. Jq1.8 5 5.1. jQuery 1.8 5 5.1.1. 可定制 5 5.1.2. 自动生

《转》MySQL 5.7版本新特性连载

MySQL 5.7版本新特性连载(一) 本文将和大家一起分享下5.7的新特性,不过我们要先从即将被删除的特性以及建议不再使用的特性说起.根据这些情况,我们在新版本及以后的版本中,应该不再使用,避免未来产生兼容性问题. 本文是基于MySQL-5.7.7-rc版本,未来可能 还会发生更多变化. 1.即将删除的特性1.1.InnoDB monitoring features,详见:WL#7377(访问地址:http://dev.mysql.com/worklog/task/?id=7377,下面的其他

TypeScript系列1-1.5版本新特性

1. 简介 随着PC端快速向移动端迁移,移动(体验)优先的概念也越来越响.由于ReactJS目前移动端仅仅支持iOS,因此移动端Web开发框架只能选择: AngularJS/Angula2 + Ionic框架 + Cordova.想要学习好Angula2以及阅读其代码, 就必须了解和学习TypeScript,也因此需要学习好ES6以及Web Component.近期将开始学习TypeScript语言. 下面先看看TypeScript语言的发展: 鉴于JavaScript这种脚本语言很难应用于大规

c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结【转载】

引用:http://blog.csdn.net/attilax/article/details/42014327 c# .net 3.5 4.0 各个版本新特性战略规划总结 1. --------------.Net Framework版本同CLR版本的关系1 2. paip.------------SDK2.0功能-------------2 2.1. 泛型:2 3. --------------sdk3.0  增加了以下功能..2 3.1. LINQ 3 4.  ----------sdk4

Atitit..jdk&#160;java&#160;各版本新特性&#160;1.0&#160;1.1&#160;1.2&#160;1.3&#160;1.4&#160;1.5(5.0)&#160;1.6(6.0)&#160;7.0&#160;8.0&#160;9.0&#160;attilax&#160;大总结

Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结 1.1. Java的编年史2 1.2. Java版本:JDK 1.02 1.3. Java版本:JDK 1.13 1.4. Java版本:JDK 1.2 (Java 2)4 1.4.1. 1999年5 1.4.2. 2000年5 1.5. Java版本:JDK 1.35 1.5.1. 2001年6 1.5.2. 2002年7

Atitit.c# .net 3.5 4.0 各个版本新特性战略规划总结

Atitit.c# .net 3.5 4.0 各个版本新特性战略规划总结 1. --------------.Net Framework版本同CLR版本的关系 1 2. paip.------------SDK2.0功能------------- 2 2.1. 泛型: 2 3. --------------sdk3.0  增加了以下功能.. 2 3.1. LINQ 3 4.  ----------sdk4.0 新加功能------------ 3 5. ].Net4.5的五项强大新特性 3 5.

JDK各版本新特性总结

JDK各版本新特性总结 JDK 1.7 新特性  1.switch中可以使用string字符串了 2.<>的运用, List<String> tempList = new ArrayList<>(); 即泛型实例化类型自动推断 3.语法上支持集合,而不一定是数组 final List<Integer> piDigits = [ 1,2,3,4,5,8 ]; 对Java集合(Collections)的增强支持,摒弃了Java集合接口的实现类,如:ArrayLi

iOS程序实现程序的版本新特性显示功能

每个程序都会多个版本,每个版本的功能会进一步优化或调整,将这些功能简明扼要的展示给急于尝鲜的用户,这就是版本新特性的功能. 程序第一次安装或升级之后的第一次启动,都会出现三到四页功能介绍页面,划屏浏览,然后才是正式进入程序.同版本的程序二次启动则没有这些介绍页.这就是版 本新特性现实界面. 如何实现这个功能呢? 需求:第一次安装或版本升级,显示新特性:同版本第二次进入,不显示新特性. 分析:程序启动会显示不同界面,就是window加载的根控制器rootViewController是不相同的.如何

Atitit 发帖机系列(8) &#160;词法分析器v5 版本新特性说明)

Atitit 发帖机系列(8)  词法分析器v5 版本新特性说明) v5  增加对sql单引号的内部支持.可以作为string 结构调整,使用递归法重构循环发..放弃循环发. V4 java dsl词法分析 使用循环 V3 sql的词法分析 atitit..sql update语法的词法分析,与语法ast构建 - V1版   anno 解析器 基于fsm设计模式 V2 Atitit.antlr实现词法分析?-?attilax /AtiPlatf_ee/src/com/attilax/fsm/Ja