Преобразование цветного растрового изображения в изображение в градациях серого с использованием только синего канала с использованием цветовой матрицы

Мне нужно растровое изображение в оттенках серого в Android, используя только канал синего цвета. Мне удалось избавиться от зеленого и красного каналов с помощью цветовой матрицы, но когда я устанавливаю насыщенность этой матрицы на 0, она игнорирует ранее внесенные изменения в красный и зеленый каналы.

Есть ли способ выполнить мою задачу? Итерация по всему массиву пикселей невозможна, так как это слишком медленно.

Я использую этот фрагмент кода:

public Bitmap ConvertToGrayscale(Bitmap bitmap) {
    int height = super.getHeight();
    int width = super.getWidth();

    float[] arrayForColorMatrix = new float[] {0, 0, 0, 0, 0,
                                               0, 0, 0, 0, 0,
                                               0, 0, 1, 0, 0,
                                               0, 0, 0, 1, 0};

    Bitmap.Config config = bitmap.getConfig();
    Bitmap grayScaleBitmap = Bitmap.createBitmap(width, height, config);

    Canvas c = new Canvas(grayScaleBitmap);
    Paint paint = new Paint();

    ColorMatrix matrix = new ColorMatrix(arrayForColorMatrix);
    matrix.setSaturation(0);

    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
    paint.setColorFilter(filter);

    c.drawBitmap(bitmap, 0, 0, paint);

    return grayScaleBitmap;
}

person Lyndon    schedule 06.11.2014    source источник


Ответы (1)


Правильная матрица для получения изображения в оттенках серого из синего канала следующая:

float[] arrayForColorMatrix = new float[] {0, 0, 1, 0, 0,
                                           0, 0, 1, 0, 0,
                                           0, 0, 1, 0, 0,
                                           0, 0, 0, 1, 0};

Из документации Android:

При применении к цвету [r, g, b, a] результирующий цвет вычисляется как (после фиксации):

R' = a*R + b*G + c*B + d*A + e;
G' = f*R + g*G + h*B + i*A + j;
B' = k*R + l*G + m*B + n*A + o;
A' = p*R + q*G + r*B + s*A + t;

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

person Lyndon    schedule 06.11.2014