Неожиданное изменение значения пикселя после setRGB и imageIO.write

Мне нужно написать серое изображение из значения, которое я генерирую. Это часть кода, которую я использую, но я делаю это просто.

BufferedImage test = new BufferedImage(1,1,BufferedImage.TYPE_BYTE_GRAY);
int rgb =(3 & 0xff) << 16 | (3 & 0xff) << 8 | (3 & 0xff);
test.setRGB(0, 0, rgb);
ImageIO.write(test, "png", new File("/home/harris/cipher.png"));

Этот код будет генерировать изображение с одним пикселем. Значение пикселя должно быть 3, но вместо этого я получил 0. что не так с этим кодом?

1 ответ

Здесь происходит несколько вещей. Сначала вы пытаетесь установить 3-байтовый цвет для 1-байтового пикселя. Глубина цвета пикселя указывается как TYPE_BYTE_GRAY. Если вместо этого вы используете TYPE_INT_RGB, код будет работать так, как написано, но не даст изображения в оттенках серого.

Если вы действительно хотите получить изображение в оттенках серого, то вам следует оставить TYPE_BYTE_GRAY. Однако вы не можете манипулировать пикселями как RGB, поэтому вы можете извлечь WriteableRaster и манипулировать этим следующим образом:

WritableRaster raster = test.getRaster();

int [] gray = new int[1];
gray[0] = 3;
raster.setPixel(0, 0, gray);

При кодировании в формате PNG этот пример фактически дает значение пикселя, равное 2. Установка значения выше 4 дает значение пикселя, равное 3. Однако при кодировании этого значения в BMP цвет записывался, как и ожидалось. Я не эксперт PNG, но, может быть, это какая-то оптимизация изображения?

Другие вопросы по тегам