2013-08-09 6 views
5

Учитывая цвет RGB в 32-разрядной целочисленной форме без знака (например, 0xFF00FF), как бы вы его инвертировали (получите отрицательный цвет), не извлекая отдельные компоненты с помощью операций с битрейтом?Как инвертировать цвет RGB в целочисленной форме?

Интересно, возможно ли использовать только побитовые операции (AND, OR, XOR).

Точнее, какой алгоритм использует наименьшее количество инструкций?

+0

0xFF00FF - всего 3 байта или 24 бит, а не 32 бит. –

+0

Меня интересуют только цвета, поэтому оставшийся байт не имеет значения и, следовательно, опущен. Спасибо за downvoting. – skrat

ответ

18

Я думаю, что это так просто. Вы можете просто вычислить 0xFFFFFF-YourColor. Это будет перевернутый цвет.

int neg = 0xFFFFFF - originalRGB 

// optional: set alpha to 255: 
int neg = (0xFFFFFF - originalRGB) | 0xFF000000; 
+2

Хотя это и инвертировало бы Альфу ... Мог бы не то, что хочет OP ... Попробуйте 0x00FFFFFF - вместо этого ваш цвет вместо – initramfs

+2

@CPUTerminator: Это не оставит альфы без изменений. Что-то вроде '(0x00FFFFFFU - (вход | 0xFF000000U)) | (input & 0xFF000000U) 'должно быть достаточно. – caf

+0

@caf Моя ошибка ... Бросил мой комментарий ... Могло только сделать (0xFFFFFFFF - Цвет) + (0xFF000000 и цвет). – initramfs

2

Вы можете просто выполнить отрицание цвета. Фрагмент:

~ color 
+1

Похоже, это самое простое решение, я предполагаю, что у него будет проблема с альфа-инвертированием – paulm

0

Ваш вопрос непонятен; никакие цвета в RGB не являются «негативными цветами».

Вы можете инвертировать изображение, как будто это был негативный фильм. Это ты имел в виду?

Если вы хотите инвертировать изображение, имеющее только один пиксель цвета 0xFF00FF, расчет заключается в вычитании из белого, 0xFFFFFF.

> negative_result_color = 0xFFFFFF - 0xFF00FF 
> negative_result_color == 0x00FF00 
true 

В компьютере вычитание выполняется добавлением комплимент: http://en.wikipedia.org/wiki/Method_of_complements#Binary_example

А если серьезно, то почему бы вам просто не позволить машину сделать вычитание для вас с вашим обычным кодом? Его то, что они хорошо at.

0
Color color_original = Color.lightGray; 

int rgb = color_original.getRGB(); 

int inverted = (0x00FFFFFF - (rgb | 0xFF000000)) | (rgb & 0xFF000000); 

Color color_inverted = new Color(inverted); 
2

Используйте этот метод для инвертирования каждого цвета и сохранения оригинальной альфы.

int invert(int color) { 
    return color^0x00ffffff; 
} 

XOR (^) с 0 возвращает исходное значение без изменений. xor с 0xff переворачивает биты. поэтому в приведенном выше случае мы имеем 0xaarrggbb, которые мы переворачиваем/инвертируем r, g и b.

Это должен быть самый эффективный способ инвертировать цвет. арифметика (незначительно) медленнее, чем эта совершенно простая побитовая манипуляция.

, если вы хотите игнорировать оригинальный альфа, и просто сделать его непрозрачным, вы можете перезаписать альфа:

int invert(int color) { 
    0xff000000 | ~color; 
} 

в этом случае мы просто переверните каждый бит цвета, чтобы инвертировать каждый канал, включая альфа, а затем замените альфа-канал на непрозрачный, заставив первые 8 бит высотой с 0xff000000.

Смежные вопросы