Думаю, название говорит достаточно. У меня есть BufferedImage полного качества, и я хочу отправить его через OutputStream с низкой битовой глубиной. Я не хочу, чтобы алгоритм изменял качество пиксель за пикселем, поэтому он все еще остается полным.

Итак, цель состоит в том, чтобы записать изображение (с полным разрешением, полным размером) через OuputStream, для записи которого требуется очень небольшое количество байтов.

Спасибо,
Мартейн

1
Martijn Courteaux 8 Мар 2010 в 21:38
1
Вы хотите минимизировать фактический передаваемый поток байтов? Если это так, то я думаю, вам следует просто использовать множество кодировщиков изображений в Java для кодирования изображения в один из очень многих форматов изображений, которые сжимаются, например (PNG - без потерь), JPG (с потерями).
 – 
David Sykes
8 Мар 2010 в 21:43
1
«bitdepth» - количество бит на пиксель. Качество менять не хочется, а что там с "битовой глубиной"?
 – 
Pindatjuh
8 Мар 2010 в 22:06

2 ответа

Лучший ответ

Вам необходимо закодировать данные изображения в формат, который имеет правильные характеристики для вашего изображения. Если это 24-битный цвет и много цветов, и вы не хотите терять качество, вы, вероятно, застряли в формате PNG, но посмотрите на JPEG 2000 без потерь.

Если можно потерять качество, то попробуйте

  1. Lossy JPEG 2000 - намного меньше, чем JPEG, при такой же потере качества
  2. уменьшение количества цветов и использование формата с отображением цветов

Если изображение содержит только серые или черно-белые данные, убедитесь, что вы кодируете их как таковые (8-битный серый или 1-битный черно-белый). Затем убедитесь, что вы используете кодировщик, настроенный для этого формата (например, TIFF с группой 4 или JBIG2).

Еще один хороший вариант - удалить все нежелательные метаданные из изображения (или убедиться, что кодировщик их не вставляет).

Если вы хотите придерживаться того, что в Java, вам, вероятно, придется использовать TIFF, PNG или JPEG - существуют сторонние кодировщики изображений (например, моя компания, Atalasoft, делает .NET-версию этих продвинутых кодировщиков - также есть поставщики Java)

К вашему сведению: уменьшение битовой глубины обычно означает снижение качества (если только уменьшение не имеет смысла). Например, если у меня есть 24-битное цветное изображение, но все цвета серые (где R == G == B), то уменьшение до 8-битного серого не приводит к потере качества. Это также верно, если ваше изображение имеет любую коллекцию из 256 различных цветов, и вы переключаетесь на формат с отображением цветов (индексированный или с палитрой). Вы уменьшаете количество байтов и не снижаете качество.

1
Lou Franco 9 Мар 2010 в 23:32

Взгляните на пакет java.util.zip, чтобы узнать все о сжатии:

http://java.sun.com/developer/technicalArticles/Programming/compression/

Хотя JPEG и PNG уже каким-то образом сжаты, используя класс Inflater, вы можете уменьшить количество байтов, сохраняя при этом такое же качество изображения. Сжатие уже сжатого формата обычно не имеет значения. Однако если вы группируете несколько изображений вместе, их раздувание имеет большое значение (поскольку методы раздувания распознают общие закономерности в данных объекта, что сокращает повторение и, таким образом, уменьшает количество байтов).

1
Pindatjuh 8 Мар 2010 в 22:01