Подтвердить что ты не робот

Как получить средний цвет изображения

Я хочу иметь возможность взять изображение и узнать, что такое средний цвет. то есть, если изображение наполовину черное полубеловое, я бы получил что-то среднее между... оттенком серого. Это может быть самый частый одиночный цвет или медиана. Любое среднее значение будет делать.

Как я могу сделать это в android.

4b9b3361

Ответ 1

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);

Ответ 2

Думаю, вам придется это сделать самому.

Просто создайте массив 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());  

Затем вы можете получить цвет с помощью intArray [0], значение может быть 0xFFFF0000 для красного (последние 6 номеров - значение цвета RGB).

ИЗМЕНИТЬ: Простое решение:

Get you full-size image in a bitmap.

Create a scaled bitmap of 1*1px.

Get this bitmap color.

Ответ 3

Создание решения Dan O, здесь метод, который автоматически учитывает альфа-канал и делает оптимизацию/компромисс между getPixels vs getPixel.

Стоимость - это память, но преимущество - производительность, вызов виртуального метода в цикле, который можно запустить несколько миллионов раз [т. 8MP-изображение имеет 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);
}

Ответ 4

Вы можете использовать класс Palete из AndroidX или из библиотеки поддержки v7.

Он предоставляет дополнительные методы для извлечения цветов из растрового изображения, такие как получение:

  • Самый доминирующий цвет
  • Яркие цвета
  • Приглушенный цвет
  • намного больше

Ответ 5

Используйте метод Bitmap.getPixels(), чтобы получить значения цвета. Затем, чтобы вычислить среднее значение, вы должны решить, что вы подразумеваете под этим. В полутоновом изображении это просто, но с цветами нет такой вещи, как средняя. Вы можете разделить на компоненты (например, RGBA) и взять среднее значение для каждого компонента. Альтернативой является поиск наиболее часто используемого цвета, и есть несколько других вариантов, которые я уверен. Играйте с ним:)