Что этот метод Java делает с побитовыми операциями? - PullRequest
3 голосов
/ 01 ноября 2011

Я не знаком с побитовыми операциями. Это алгоритм манипуляции с изображениями. Что происходит?

void binarize50(int pixels[]) {
        for(int i = 0; i < pixels.length; i++) {
            int gray = ((pixels[i] & 0xff) + ((pixels[i] & 0xff00) >> 8) + ((pixels[i] & 0xff0000) >> 16)) / 3;
            pixels[i] = gray < 128 ? 0xff000000 : 0xffffffff;
        }
}

Я обнаружил, что (пиксели [i] и 0xff) просто как-то "нормализуется" и позволил пикселю / байту стать положительным значением между 0..255.

Что делают (пиксели [i] & 0xff00 >> 8)?
Что такое 0xff00? И почему, если серый <128, пиксель становится 0xff000000 или 0xffffffff? </p>

Ответы [ 5 ]

5 голосов
/ 01 ноября 2011

Операция & с 0xff и т.п. применяет битовую маску.Это побитовая и операция.Поскольку int в Java является 32-битным, вы можете читать 0xff как 00000000_00000000_00000000_11111111, 0xff00 как 00000000_00000000_11111111_00000000 и так далее.Они просто пропускают ведущие нули.

Так что, если вы делаете pixels[i] & 0xff, то происходит то, что вы получаете целое число, последние 8 битов которого совпадают с пикселями [i], а остальные установлены наноль.

Оператор >> - это сдвиг вправо.Это сместит битовую комбинацию вправо на указанное количество битов.Если b содержит 00110011_11001100_00010110_01001100, а вы b >> 8, вы получите 00000000_00110011_11001100_00010110.Последние 8 битов «выпали», в то время как влево смещены нули. Я не помню, сместится ли эта операция на 1 влево, если начальный бит был 1, поэтому, возможно, кто-то может подтвердить или опровергнуть это.

Зная это, давайте взглянем на эту строку:

int gray = ((pixels[i] & 0xff) + ((pixels[i] & 0xff00) >> 8) + ((pixels[i] & 0xff0000) >> 16)) / 3;

Здесь происходит то, что мы делаем int следующим образом (не точный порядок выполнения кода, просто для иллюстрации):

  • пикселей [i] маскируется, поэтому сохраняются только последние 8 битов, остальные становятся равными 0.
  • пикселей [i] маскируется, так что только биты 8 - 15 (считая справа)слева, начиная с 0), остальные становятся 0. Затем результат сдвигается на 8 бит вправо.Если бы мы начали с 00001111_00001111_10101010_00110011, это привело бы к 00000000_00000000_00000000_10101010.
  • пикселей [i] замаскировано, так что сохраняются только биты 16 - 23, а затем сдвинуто на 16 бит вправо.
  • результатыиз вышеперечисленных трех операций добавляются и ...
  • этот результат делится на 3.

Так чего же это дает?Что же, в сущности, сводится к тому, что первые 8 бит пикселей [i] игнорируются, а следующие 3 секции по 8 битов интерпретируются как одно значение от 0 до 255, из которого берется среднее значение.

Затем этот результат сравнивается со 128. Если оно меньше, то в пикселях [i] я устанавливаю 0xff000000, в противном случае он устанавливается в 0xffffffff.

Это типичное изменение тренда, с которым вы можете столкнуться при операциях с цветами.закодированы как целыеВероятно, это схема argb, где первые 8 битов int являются альфа-каналом (прозрачность), следующие 8 битов красного цвета, следующие 8 битов зеленого цвета, а последние 8 битов синего цвета.Или его вариант.0xff000000 будет полностью непрозрачным черным, а 0xffffffff - полностью непрозрачным белым.

5 голосов
/ 01 ноября 2011

Что это делает, зависит от цветовой модели и того, как цвета представлены в памяти.

Я предполагаю, что оно превращает обычное изображение ARGB в черно-белое изображение с пороговым значением 50%. (Все пиксели с «яркостью» менее 50% становятся полностью черными, а все остальные - полностью белыми.)

Что делает (pixels[i] & 0xff00 >> 8)?

  • pixel[i] вы уже знаете: -)
  • & ff00 маскирует биты во втором байте
  • >> 8 сдвигает биты вправо, на восемь позиций (т. Е. Делает самый правый байтовый спад края)

Что такое 0xff00?

0xff00 - шестнадцатеричный литерал для значения 65280 (или 1111111100000000 в двоичном виде)

И почему, если серый <128, пиксель становится 0xff000000 или 0xffffffff? </em>

Эта строка:

int gray = ((pixels[i] & 0xff) +
            ((pixels[i] & 0xff00) >> 8) +
            ((pixels[i] & 0xff0000) >> 16)) / 3;

складывает красный, зеленый и синий компоненты и делит их на три (определяет среднее значение).

Эта строка

pixels[i] = gray < 128 ? 0xff000000 : 0xffffffff;

предположительно говорит, что если серость меньше половины, пиксель должен быть полностью черным, в противном случае он должен быть полностью белым.

2 голосов
/ 01 ноября 2011

(пиксели [i] и 0xff) = значение синего цвета от 0 до 255

(пикселей [i] и 0xff00) >> 8 = значение зеленого в диапазоне от 0 до 255

(пиксели [i] и 0xff0000) >> 16) = значение красного в диапазоне от 0 до 255

Затем вы берете среднее значение из 3 значений, найденных выше.

После этого, в зависимости от серости, сделайте его белым или черным, т. Е. Менее 50% серого будет черным или белым.

1 голос
/ 01 ноября 2011

0xFF00 это битовая маска означает 1111111100000000 в двоичном представлении.

Таким образом, когда вы применяете эту маску к числу, вы оставляете старшие 8 битов.

Оператор >> означает сдвиг вправо.Например 11110000 >> 2 = 00111100

1 голос
/ 01 ноября 2011

(pixels[i] & 0xff00) >> 8 берет второй байт от целого, который представляет зеленый цвет - & делает все биты кроме нуля 8-15 и >> сдвигает их на 8 бит вправо, так что если числоравно (в битах) 0101000100001100:

0101000100001100 & 0xff = 0101000100001100 & 1111111100000000 = 0101000100000000.
0101000100000000 >> 8 = 01010001

То же самое для ((pixels[i] & 0xff0000) >> 16).

Нет, вы берете их среднее значение (/3) и получаете, ближе ли цвет кбелый или черный (gray < 128).В соответствии с этим вы можете сделать пиксель черным или белым.

...