在Android @drawable中查找图像的主色

sty*_*972 47 android colors bitmap drawable

如果使用Windows 7,您可以理解为什么我试图在图像中找到主色.当您将鼠标悬停在任务栏中的程序上时,该特定程序的背景会根据图标中最主要的颜色而变化.我已经注意到其他程序中使用的这种技术,但是不能记住它们.

我可以看到这对我用于开发应用程序的一些UI技术很有用,我想知道如何从Android可绘制资源中找到最常见的颜色.

Ton*_*ham 71

在Android 5.0 Lollipop中,添加了一个类来帮助从Bitmap中提取有用的颜色.在android.support.v7.graphics中找到的Palette类可以提取以下颜色:

  • 充满活力
  • 充满活力的黑暗
  • 充满活力的光芒
  • 静音
  • 柔和的黑暗
  • 柔和的光

这个Android培训页面提供了使用该课程所需的所有详细信息(我在Android Studio中自己尝试过,这非常简单):http://developer.android.com/training/material/drawables.html#ColorExtract

报价:

Android支持库r21及更高版本包含Palette 类,可让您从图像中提取突出的颜色.要提取这些颜色,请将Bitmap对象传递给加载图像的后台线程中的Palette.generate()静态方法.如果您不能使用该线程,请调用Palette.generateAsync()方法并改为提供侦听器.*

您可以使用Palette类中的getter方法从图像中检索突出的颜色,例如Palette.getVibrantColor.

要在项目中使用Palette类,请将以下Gradle依赖项添加到应用程序的模块中:

dependencies {
    ...
    implementation 'com.android.support:palette-v7:21.0.+'
}
Run Code Online (Sandbox Code Playgroud)

*如果您需要使用generateAsync(),请按以下步骤操作:

implementation 'androidx.palette:palette:1.0.0'
Run Code Online (Sandbox Code Playgroud)

编辑:由于问题是如何从可绘制资源中提取颜色,您首先必须将drawable转换为位图以使用我所描述的技术.幸运的是,使用BitmapFactory非常简单:

Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
    public void onGenerated(Palette palette) {
        // Do something with colors...
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.这使得大多数可用的库和方法都是多余的. (2认同)
  • Palette.generateAsync方法已被弃用.请改用Palette.from(bitmap).generate(paletteListener) (2认同)
  • @Spritzig使用来自:`Palette.from(bitmap).generate(new PaletteAsyncListener(){public void onGenerated(Palette p){//使用生成的实例}});` (2认同)

小智 30

还有另一个解决方案,它更接近,但如果你不想长时间搜索颜色,它可以完成这项工作.

public static int getDominantColor(Bitmap bitmap) {
    Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, 1, 1, true);
    final int color = newBitmap.getPixel(0, 0);
    newBitmap.recycle();
    return color;
}
Run Code Online (Sandbox Code Playgroud)

  • 好的方法,但是不能返回适当的颜色! (2认同)

Fra*_*cis 11

要从图像中找到显性/鲜艳/柔和的颜色,请使用Palette

进口:

implementation 'androidx.palette:palette:1.0.0'
Run Code Online (Sandbox Code Playgroud)

用法:

    val bitmap = BitmapFactory.decodeResource(resources, R.drawable.image)

    Palette.Builder(bitmap).generate { it?.let {  palette ->
        val dominantColor = palette.getDominantColor(ContextCompat.getColor(context!!, R.color.defaultColor))

        // TODO: use dominant color

    } }
Run Code Online (Sandbox Code Playgroud)

  • 最新版本可在 https://developer.android.com/jetpack/androidx/releases/palette 上找到 (2认同)

Rei*_*rth 7

此类迭代Bitmap并返回最主要的颜色.请在必要时随意清理代码.

public class ImageColour {

String colour;


public ImageColour(Bitmap image) throws Exception {

     int height = image.getHeight();
     int width = image.getWidth();

     Map m = new HashMap();

        for(int i=0; i < width ; i++){

            for(int j=0; j < height ; j++){

                int rgb = image.getPixel(i, j);
                int[] rgbArr = getRGBArr(rgb);                

                if (!isGray(rgbArr)) {   

                        Integer counter = (Integer) m.get(rgb);   
                        if (counter == null)
                            counter = 0;
                        counter++;                                
                        m.put(rgb, counter);       

                }                
            }
        }        

        String colourHex = getMostCommonColour(m);
    }



    public static String getMostCommonColour(Map map) {

        List list = new LinkedList(map.entrySet());
        Collections.sort(list, new Comparator() {
              public int compare(Object o1, Object o2) {

                return ((Comparable) ((Map.Entry) (o1)).getValue())
                  .compareTo(((Map.Entry) (o2)).getValue());

              }

        });    

        Map.Entry me = (Map.Entry )list.get(list.size()-1);
        int[] rgb= getRGBArr((Integer)me.getKey());

        return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);        
    }    


    public static int[] getRGBArr(int pixel) {

        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;

        return new int[]{red,green,blue};

  }

    public static boolean isGray(int[] rgbArr) {

        int rgDiff = rgbArr[0] - rgbArr[1];
        int rbDiff = rgbArr[0] - rgbArr[2];

        int tolerance = 10;

        if (rgDiff > tolerance || rgDiff < -tolerance) 
            if (rbDiff > tolerance || rbDiff < -tolerance) { 

                return false;

            }                

        return true;
    }


public String returnColour() {

    if (colour.length() == 6) {
        return colour.replaceAll("\\s", "");
    } else {
        return "ffffff";
    }
}
Run Code Online (Sandbox Code Playgroud)

得到十六进制只是打电话 returnColour();


Wil*_*pes 5

添加到依赖项

implementation 'androidx.palette:palette:1.0.0'
Run Code Online (Sandbox Code Playgroud)

和..

 AppCompatImageView imageView = findViewById(R.id.image_view);

 Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
 Palette.from(bitmap).generate(palette -> {
      int vibrant = palette.getVibrantColor(0x000000); // <=== color you want
      int vibrantLight = palette.getLightVibrantColor(0x000000);
      int vibrantDark = palette.getDarkVibrantColor(0x000000);
      int muted = palette.getMutedColor(0x000000);
      int mutedLight = palette.getLightMutedColor(0x000000);
      int mutedDark = palette.getDarkMutedColor(0x000000);
 });
Run Code Online (Sandbox Code Playgroud)