Запись в 16-битный BufferedImage TYPE_USHORT_GRAY

Я пытаюсь записать 16-битные изображения в градациях серого в png, используя BufferedImage.TYPE_USHORT_GRAY. Обычно я пишу изображение так:

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

затем:

image.setRGB(x,y,Color.getRGB);

установить пиксели и, наконец:

ImageIO.write(image, "png", new File(path + ".png"));

записать в изображение PNG.

Но теперь у меня есть это как изображение:

BufferedImage imageGray = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);

Как мне сохранить пиксели в этом формате? Использование setRGB() с 16-битным целым числом, похоже, не работает, когда я открываю сохраненный файл png, я вижу, что происходит много полос.

Я попытался сохранить простой градиент от 0 до 65535, а затем с помощью setRGB() на изображении в градациях серого и проверил результаты в Photoshop. Я вижу, что изображение состоит из меньших градиентов каждые 256 строк. Я предполагаю, что setRGB() или imageIO не работают так, как мне бы хотелось.

Есть ли обходные пути для этого? Поддерживает ли imageIO формат BufferedImage.TYPE_USHORT_GRAY? Или это может только сохранить 8-битные данные? И если он может сохранять 16-битные данные, как бы я сохранил пиксельные данные, предпочтительно таким образом, как работает setRGB() (так для определенной координаты x,y)?

4 ответа

Решение

Как pst уже прокомментировал ниже моего вопроса, все, что мне нужно было сделать, это получить доступ к Растру напрямую. Задача решена!

Вам, вероятно, нужно расширить подписанные 16-битные шорты до целых и удалить знак:

int ushort = (int)(shortData[x][y]) & 0xFFFF;

От BufferedImage ты можешь читать

public static final int TYPE_USHORT_GRAY

Представляет неподписанное короткое изображение в градациях серого, не проиндексированное). Это изображение имеет ComponentColorModel с CS_GRAY ColorSpace.

Так что попробуйте создать свой собственный ColorSpace с CS_GRAY тип (ColorSpace.getInstance(ColorSpace.CS_GRAY) должен сделать это, я полагаю). Этот объект имеет метод с именем fromRGB который вы должны быть в состоянии использовать...

      BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
short[] dataArray = ((DataBufferUShort)image.getRaster().getDataBuffer()).getData();
dataArray[y*width+x] = color;
ImageIO.write(image, "png", new File(path + ".png"));
Другие вопросы по тегам