如何获得图像的平均颜色

cod*_*441 34 java android

我希望能够拍摄图像并找出平均颜色.意思是如果图像是半黑半白,我会得到介于两者之间的东西......有些灰色.它可能是最常见的单色或中值.任何平均值都可以.

我怎么能在android中做到这一点.

Dan*_*n O 45

Bitmap bitmap = someFunctionReturningABitmap();
long redBucket = 0;
long greenBucket = 0;
long blueBucket = 0;
long pixelCount = 0;

for (int y = 0; y < bitmap.getHeight(); y++)
{
    for (int x = 0; x < bitmap.getWidth(); x++)
    {
        Color c = bitmap.getPixel(x, y);

        pixelCount++;
        redBucket += Color.red(c);
        greenBucket += Color.green(c);
        blueBucket += Color.blue(c);
        // does alpha matter?
    }
}

Color averageColor = Color.rgb(redBucket / pixelCount,
                                greenBucket / pixelCount,
                                blueBucket / pixelCount);
Run Code Online (Sandbox Code Playgroud)

  • 在循环中使用`getPixel`单独获取每个像素是浪费和缓慢的.你应该在for循环之前通过一次调用`getPixels`获得所有像素. (4认同)
  • 慢的?可能是。浪费?也许,取决于位图的大小和可用内存的大小(我相信“getPixels()”创建位图数据的副本)。 (2认同)
  • `Color c = bitmap.getPixel()` 应该是 `int c = bitmap.getPixel()` 因为 `getPixel()` 返回一个 int,而不是一个 Color (2认同)

Ste*_*his 11

我想你必须自己做.

只需创建一个包含所有颜色的int数组:

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);  
    bmp = bmp.copy(Bitmap.Config.ARGB_8888, true);    
    int intArray[] = new int[bmp.getWidth()*bmp.getHeight()];  
    bmp.getPixels(intArray, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight());  
Run Code Online (Sandbox Code Playgroud)

然后你可以用intArray [0]获得颜色,红色的值可以是0xFFFF0000(最后6个数字是RGB颜色值).

编辑:简单的解决方案:

Get you full-size image in a bitmap.

Create a scaled bitmap of 1*1px.

Get this bitmap color.
Run Code Online (Sandbox Code Playgroud)

  • 第二种解决方案获得最常见的颜色而不是平均颜色。 (3认同)

Tom*_*Tom 9

建立Dan O的解决方案,这是一种自动考虑alpha通道并对getPixelsvs 进行优化/权衡的方法getPixel.

成本是内存,但好处是性能,在循环中调用虚拟方法可能会运行数百万次[即800万像素图像有3,456x2,304 = 7,962,624像素]).我甚至通过删除循环android.graphics.Color方法调用更进一步.

public static int getDominantColor(Bitmap bitmap) {
   if (null == bitmap) return Color.TRANSPARENT;

   int redBucket = 0;
   int greenBucket = 0;
   int blueBucket = 0;
   int alphaBucket = 0;

   boolean hasAlpha = bitmap.hasAlpha();
   int pixelCount = bitmap.getWidth() * bitmap.getHeight();
   int[] pixels = new int[pixelCount];
   bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());

   for (int y = 0, h = bitmap.getHeight(); y < h; y++)
   {
       for (int x = 0, w = bitmap.getWidth(); x < w; x++)
       {
           int color = pixels[x + y * w]; // x + y * width
           redBucket += (color >> 16) & 0xFF; // Color.red
           greenBucket += (color >> 8) & 0xFF; // Color.greed
           blueBucket += (color & 0xFF); // Color.blue
           if (hasAlpha) alphaBucket += (color >>> 24); // Color.alpha
       }
   }

   return Color.argb(
           (hasAlpha) ? (alphaBucket / pixelCount) : 255,
           redBucket / pixelCount,
           greenBucket / pixelCount,
           blueBucket / pixelCount);
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,你计算8 _megapixel_图像中的像素数,其名称为800万像素.但是感谢解决方案. (2认同)
  • 800万像素不精确,7,962,624像素精确. (2认同)

ale*_*leb 8

您可以使用AndroidX中的Palete类或v7-support库中的类.

它提供了从Bitmap中提取颜色的其他方法,例如获取:

  • 最主要的颜色
  • 鲜艳的色彩
  • 柔和的颜色
  • 多得多