Как преобразовать RGB в BGR?

Это, вероятно, легко, но я пытаюсь преобразовать из источника, который предоставляет цвета в строках RGB, в вывод в строках BGR в Java. Я тратил свой мозг и время на переключение и Long.decode и Long.toHexString.

Не стесняйтесь также добавлять туда альфа-значения (RGBA -> ABGR), хотя я думаю, что могу расширить принципы.

Я могу предположить, что шестнадцатеричный код имеет форму, указанную в long и int декодировать:

0x HexDigits  
0X HexDigits 
# HexDigits

person Adam    schedule 14.06.2010    source источник


Ответы (5)


Для 24-битных цветов (по 8 бит для каждого из R, G, B):

String rgbSource = getRGBSource(); //your function to get a string version of it
int in = Integer.decode(rgbSource);
int red = (in >> 16) & 0xFF;
int green = (in >> 8) & 0xFF;
int blue = (in >> 0) & 0xFF;
int out = (blue << 16) | (green << 8) | (red << 0);
person Mike    schedule 14.06.2010
comment
хороший ответ! Это сработало, если бы я переключил имена цветовых переменных в порядок: красный, зеленый, синий. - person Adam; 15.06.2010
comment
Этот метод также работает при добавлении необязательного альфа-канала, если шаблон продолжается. Вы можете использовать следующее из моего ответа, чтобы автоматически добавить непрозрачный альфа-канал, если он отсутствует: long rgba = (rgbSource.length () ‹8? Long.decode (rgbSource + ff): Long.decode (rgbSource)); // декодирует несколько шестнадцатеричных форматов и устанавливает альфа - person Adam; 16.06.2010

int abgr = Integer. reverseBytes (rgba);


Включая вспомогательный код, при условии, что можно безопасно решить, нужно ли добавлять альфа-канал в зависимости от длины строки (например, рассмотрим "0xFFFFFF".length()):

String rgb = getRGB();

//decodes a number of hex formats and sets alpha
int rgba = rgb.length() < 8 ? 
           Long.decode(rgb + "ff").intValue() : 
           Long.decode(rgb       ).intValue();

int abgr = Integer.reverseBytes(rgba);

Вот однострочный метод:

public static String reverseRGB(String rgba) {
    return String.format("%08X",Integer.reverseBytes(Long.decode(rgba.length() < 8 ? rgba + "ff" : rgba).intValue()));
}
person Stephen Denne    schedule 14.06.2010
comment
выглядит привлекательно, но int in = Integer.decode (preferenceValue); Строка abgrColor = Integer.toHexString (Integer.reverseBytes (in)); имел # 00ff0d - ›dff0000 - person Adam; 15.06.2010
comment
@Adam, поэтому я включил в имена переменных. Если вы добавите ff в конце, используя свой код, то # 00ff0dff станет ff0dff00 - person Stephen Denne; 15.06.2010
comment
Думаю, я запутался. Я думал, что для альфа-версии потребуется long, потому что #ffffffff (непрозрачный белый) больше, чем int max. Когда я попробовал эту же идею с лонгами, результат был еще более далеким. Вы использовали беззнаковые целые числа? - person Adam; 16.06.2010
comment
@Adam, Java не имеет беззнаковых целых чисел, но у нее есть методы в Integer, которые работают с 32 битами, игнорируя особый статус старшего бита как знакового бита. Метод reverseBytes использует ››› 24 для выполнения логического сдвига вправо старших байтов, избавляя от необходимости выполнять И с 0xFF. - person Stephen Denne; 16.06.2010
comment
@Stephen Как сохранить rbga #ffffffff в int (4 294 967 295 ›2 147 483 647)? Извините за мое незнание вопроса. Вы конвертируете int обратно в long для Long.toHexString? - person Adam; 17.06.2010
comment
Функции декодирования @Adam как Integer, так и Long требуют, чтобы часть шестнадцатеричных цифр представляла положительные числа со знаком минус для обозначения отрицательных чисел, поэтому я рекомендую использовать функцию декодирования Long. Затем Long.intValue () возвращает младшие 32 бита, которые интерпретируются как целое число со знаком с дополнением до двух, равное -1. - person Stephen Denne; 17.06.2010
comment
@Adam javadocs на Integer.toHexString говорит, что целое число рассматривается как целое число без знака, поэтому нет необходимости использовать Long, хотя это не имеет никакого значения. Еще большее беспокойство вызывает то, что оба метода toHexString возвращают только шестнадцатеричные символы, достаточные для представления числа. Вам, вероятно, будет лучше использовать String.format (% 08X, abgr); - person Stephen Denne; 17.06.2010
comment
@Stephen Я ценю вашу помощь в этом, но этот метод все еще не работает для меня. Обратите внимание, что отсутствие начальных нулей в моем случае - это нормально, но мне нравится ваш формат (+1). длинное число = (rgba .length () ‹8? Long.decode (rgba + ff): Long.decode (rgba)); Строка abgrColor = Long.toHexString (Integer.reverseBytes ((int) number)); Результаты в # d90d8e - ›ffffffff - person Adam; 01.07.2010
comment
@Adam Long.toHexString возвращает ffffffffff8e0dd9 - person Stephen Denne; 05.07.2010
comment
@ Стивен А, я вижу, что происходит. Затем я поместил это значение в документ kml, где были прочитаны только первые 8 символов. Спасибо за помощь! - person Adam; 07.07.2010

Если ввод представляет собой 6-символьную строку rgb:

String bgr = rgb.substring(4,6) + rgb.substring(2,4) + rgb.substring(0,2);

Если ввод представляет собой 8-символьную строку rgba:

String abgr = rgba.substring(6,8) + rgba.substring(4,6) + rgba.substring(2,4) + rgba.substring(0,2);

Если вход - это int с 8-битными каналами:

String bgr = String.format( "%02X%02X%02X" , rgb & 0x00FF , (rgb>>8) & 0x00FF , (rgb>>16) & 0x00FF );
String abgr = String.format( "%02X%02X%02X%02X" , rgba & 0x00FF , (rgba>>8) & 0x00FF , (rgba>>16) & 0x00FF , (rgba>>24) & 0x00FF );
// or
String bgr = String.format( "%06X" , Integer.reverseBytes( rgb ) >> 8 );
String abgr = String.format( "%08X" , Integer.reverseBytes( rgba ) );
person drawnonward    schedule 14.06.2010
comment
Этот ответ тоже хорош, но он не обладает надежностью использования функции декодирования при работе с #rrggbb или 0xrrggbb - person Adam; 15.06.2010

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

long number = (rgb.length() < 8 ? Long.decode(rgb+ "ff") : Long.decode(rgb)); //decodes a number of hex formats and sets alpha
String abgrColor = (new StringBuilder())
.append((Long.toHexString((number) & 0xFF).length()==2? Long.toHexString((number) & 0xFF): "0"+Long.toHexString((number) & 0xFF)))
.append((Long.toHexString((number>>8) & 0xFF).length()==2? Long.toHexString((number>>8) & 0xFF): "0"+Long.toHexString((number>>8) & 0xFF)))
.append((Long.toHexString((number>>16) & 0xFF).length()==2? Long.toHexString((number>>16) & 0xFF): "0"+Long.toHexString((number>>16) & 0xFF)))
.append((Long.toHexString((number>>24) & 0xFF).length()==2? Long.toHexString((number>>24) & 0xFF): "0"+Long.toHexString((number>>24) & 0xFF)))
.toString();
person Adam    schedule 14.06.2010

Это должно сработать.

public static int swapByte1And3(int inValue) {
        int swap = inValue & 0xFF;
        swap = swap << 16 | (inValue >>> 16 & 0xFF);
        return inValue & 0xFF00FF00 | swap;
    }

    public static int convertBRGtoRBG(int inColor) {
        return swapByte1And3(inColor);
    }

    public static int convertABRGtoRBGA(int inColor) {
        int swap = inColor >>> 24;
        inColor = convertBRGtoRBG(inColor) << 8;
        return inColor | swap;
    }
person xxx    schedule 05.09.2012