со знаком int на неподписанный байт и наоборот - PullRequest
1 голос
/ 20 апреля 2011

У меня есть подписанное значение, например -7368817 когда я приведу его к байту, это будет что-то вроде: -113 Я конвертирую его в неподписанный байт до & 0xff, и это будет что-то вроде 143 теперь я манипулирую этим байтовым значением и после этого хочу вернуться обратно! получить подписанное целое число нового байта. :)

Обновление

Вся история:

У меня есть изображение с 8-битной глубиной и серой шкалой! это означает, что все пиксели представлены с использованием 1 байта

BufferedImage image = ImageIO.read(new File("my_grayscal_8bit_photo.jpg"));

int intPixel = image.getRGB(1, 1);

теперь мне нужно немного битовых манипуляций в этом пикселе, но так как это int, я должен сначала преобразовать его в байт:

byte bytePixel = (byte) intPixel;

и сделать его без знака:

int intPixel2 = bytePixel & 0xff;

Теперь я делаю свои битовые манипуляции и хочу преобразовать их в int и сделать:

image.setRGB(1, 1, neworiginalint);

Ответы [ 2 ]

4 голосов
/ 20 апреля 2011

Метод getRGB(int x, int y) всегда возвращает int пиксель в цветовой модели TYPE_INT_ARGB.Чтобы вручную извлечь значения красного, зеленого, синего и альфа-канала для пикселя, вы можете сделать это:

int pixel = image.getRGB(1, 1);
int a = (pixel >> 24) & 0xFF;
int r = (pixel >> 16) & 0xFF;
int g = (pixel >> 8) & 0xFF;
int b = pixel & 0xFF;

или использовать для удобства конструктор Color(int rgba, boolean hasalpha) (за счет производительности).После того, как вы изменили значения красного, зеленого, синего и альфа (в диапазоне от 0 до 255), вы можете снова объединить их в int для установки пикселей:

int newPixel = (a << 24) | (r << 16) | (g << 8) | b;

Использование -7368817пиксель, который вы упомянули с помощью этого кода, альфа равна 255 (поэтому прозрачности нет), а значения красного, зеленого и синего равны 143. Поскольку вы работаете с оттенками серого, вы можете просто выбрать любой из красного, зеленого или синего, чтобы получить серый цвет.значение.Однако при настройке пикселя вы должны установить все три для поддержания градаций серого, так как это RGB.Вы можете кратко обозначить его примерно так:

int pixel = image.getRGB(1, 1);

// extract your gray value from blue, assume red and green are same
int gray = pixel & 0xFF; 

// this method does your manipulation on the gray value, 0 to 255
gray = manipulate(gray);

// recombine back into int, preserving the original alpha
int newPixel = (pixel & 0xFF000000) | (gray << 16) | (gray << 8) | gray;

// now you can set your new pixel
image.setRGB(1, 1, nexPixel);

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

1 голос
/ 20 апреля 2011

Вы спрашиваете, как манипулировать младшим значащим байтом в int со знаком, не касаясь более значимого байта?
Это можно сделать так:

int i = -7368817; // 0xFF8F 8F8F
int b = i & 0xFF; // "signed byte", = 0x8F = 143
b += 0x2C; // your manipulation, result = 0xBB
i = (i & 0xFFFFFF00) | (b & 0xFF); // result of LSB modification = 0xFF8F8FBB

или за один шаг: i = (i & 0xFFFFFF00) | ((i + 0x2C) & 0xFF);, если это простая манипуляция.

Если манипуляция не может привести к переполнению, вы можете просто сделать это для целого int:
i ^= 0x34; // i = 0xFF8F8FBB

...