Всплеск цвета Android

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

Я попытался использовать проверку цвета по пикселям и затем заменить цвет, но он слишком медленный для больших изображений.

int width = originalImage.getWidth();
int height = originalImage.getHeight();
int[] pixels = new int[width * height];
originalImage.getPixels(pixels, 0, width, 0, 0, width, height);

for (int x = 0; x < pixels.length; ++x) {
     pixels[x] = Distance(pixels[x], fromColor) < 4 ? targetColor : pixels[x];
}

Bitmap newImage = Bitmap.createBitmap(width, height, originalImage.getConfig());
newImage.setPixels(pixels, 0, width, 0, 0, width, height);


public int Distance(int a, int b) {
     return Math.abs(Color.red(a) - Color.red(b)) + Math.abs(Color.green(a) -
                     Color.green(b)) + Math.abs(Color.blue(a) - Color.blue(b));
}

РЕДАКТИРОВАТЬ:

Вот оригинальные и обработанные изображения, цвет, который я сохраняю, # ff9350: enter image description here enter image description here

Ответ 1

Вы можете попробовать перечислить возможные значения цвета RGB и подготовить HashSet содержащий только те значения цвета, которые не должны быть ненасыщенными. Кажется, что не должно быть много значений.

После этого вы сможете проверить, должен ли цвет быть ненасыщенным или нет. Таким образом, вы получите довольно долгий предварительный расчет для нового заданного цвета, но ваш код, который преобразует фотографию, станет быстрее.

Он может быть реализован так (не тестировал его под Android, просто какой-то псевдокод Java чтобы показать эту идею):

// precalculation
Set<Color> keptColors = new HashSet<Color>();
final int MAX_DISTANCE = 4;
for (int r=red(fromColor)-MAX_DISTANCE; r<=red(fromColor)+MAX_DISTANCE; r++) {
    for (int g=green(fromColor)-MAX_DISTANCE; g<=green(fromColor)+MAX_DISTANCE; g++) {
        for (int b=blue(fromColor)-MAX_DISTANCE; b<=blue(fromColor)+MAX_DISTANCE; b++) {
            if (Distance(rgb(r,g,b)), fromColor) < MAX_DISTANCE {
                keptColors.add(rgb(r,g,b));
            }
        }
    }
}
...

// in you photo processing code
keptColors.contains(pixels[x]) ? pixels[x] : targetColor;