Понимание выходных значений BufferedImage.getRGB
Я получаю целочисленное значение для пикселя в изображении, используя этот метод:
int colour = img.getRGB(x, y);
Затем я распечатываю значения, и я вижу, что черные пиксели соответствуют значению типа "-16777216", своего рода синему, что-то вроде "-16755216" и т.д. Может ли кто-то объяснить мне логику этого стоимость?
Ответы
Ответ 1
getRGB(int x, int y)
возвращает вам значение цветного пикселя в месте (x, y).
Вы неверно интерпретируете возвращаемое значение.
Он находится в двоичном формате. как 11... 11010101, и это дано вам как значение int.
Если вы хотите, чтобы компоненты RGB (т.е. Red, Green, Blue) использовали это значение, используйте Color class. например
Color mycolor = new Color(img.getRGB(x, y));
Затем вы можете получить значение красного, зеленого или синего, используя getRed()
, getGreen()
, getBlue()
, getAlpha()
. Тогда значение int
будет возвращено этими методами в знакомом формате, имеющем значение 0 < value < 255
int red = mycolor.getRed();
Если вы не хотите использовать класс Color
вам нужно будет использовать побитовые операции, чтобы получить его значение.
Ответ 2
Цвет RGB int
содержит красные, зеленые, синие компоненты цвета в битах. Вы должны посмотреть на его двоичное или шестнадцатеричное представление и не смотреть на него как целое целое число (не смотреть на его десятичное представление).
An int
имеет 32 бита, 3x8 = 24 используется для хранения RGB-компонентов (по 8 бит для каждого) в следующем формате:
2 1 0
bitpos 32109876 54321098 76543210
------ --+--------+--------+--------+
bits ..|RRRRRRRR|GGGGGGGG|BBBBBBBB|
Вы можете извлечь или установить компоненты с помощью битмаски:
int color = img.getRGB(x, y);
// Components will be in the range of 0..255:
int blue = color & 0xff;
int green = (color & 0xff00) >> 8;
int red = (color & 0xff0000) >> 16;
Если цвет также имеет ARGB-компонент (прозрачность), он получает последние оставшиеся 8 бит.
3 2 1 0
bitpos 10987654 32109876 54321098 76543210
------ +--------+--------+--------+--------+
bits |AAAAAAAA|RRRRRRRR|GGGGGGGG|BBBBBBBB|
И значение:
int alpha = (color & 0xff000000) >>> 24; // Note the >>> shift
// required due to sign bit
Значение альфа 255 означает, что цвет полностью непрозрачен, а значение 0 означает, что цвет полностью прозрачен.
Ваш цвет:
Ваш цвет color = -16755216
, который имеет:
blue : 240 // Strong blue
green: 85 // A little green mixed in
red : 0 // No red component at all
alpha: 255 // Completely opaque
Ответ 3
Он объясняется в документах:
Возвращает целочисленный пиксель в цветной модели RGB по умолчанию (TYPE_INT_ARGB) [...]
Итак, вы получаете 8-битный альфа-канал, 8 бит красный, 8 бит зеленый, 8 бит синий.
Простым (и медленным способом) для проверки значения является использование new java.awt.Color(colour, true);
, а затем вызов геттеров.
Или вы можете распечатать это значение в виде шестизначного значения без знака: Integer.toString(colour, 16)
. Каждые два символа вывода будут одной частью набора ARGB.
Ответ 4
См. Реализацию ColorModel.getRgb
:
589 public int getRGB(int pixel) {
590 return (getAlpha(pixel) << 24)
591 | (getRed(pixel) << 16)
592 | (getGreen(pixel) << 8)
593 | (getBlue(pixel) << 0);
594 }
Ответ 5
На самом деле, вы можете преобразовать int в двоичную строку Integer.toBinaryString(-16755216), которая равна 11111111000000000101010111110000.it, которая состоит из 4 байтов: альфа, красный, зеленый, синий. Значения не преломляются, то есть любая прозрачность сохраняется только в альфа-компоненте, а не в цветовых компонентах. Компоненты хранятся следующим образом (альфа < 24) | (красный < 16) | (зеленый < 8) | синий. Каждый компонент находится в диапазоне от 0,255 до 0, что означает отсутствие вклада для этого компонента, а 255 означает 100% вклад. Таким образом, непрозрачный черный будет 0xFF000000 (100% непрозрачный, но без вкладок от красного, зеленого или синего), а непрозрачный белый будет 0xFFFFFFFF.