Я пытаюсь преобразовать изображение прямой цветовой модели в битональное индексированное изображение (1 бит на пиксель) и сохранить индексированное изображение как BMP.
Как указано на домашней странице Java Advanced Imaging API:
Битовая глубина закодированного вывода определяется битовой глубиной исходного изображения.
При просмотре исходного кода BMPImageWriter
механизмом этого является возврат значение ColorModel # getPixelSize ().
Используя уменьшенную копию изображения из Wikimedia Commons, я сначала выполняю квантование цвета для получения таблицы поиска цветов, а затем распространение ошибок для применения дизеринга Флойда – Стейнберга:
PlanarImage surrogateImage = PlanarImage.wrapRenderedImage(image);
PlanarImage op = ColorQuantizerDescriptor.create(surrogateImage, ColorQuantizerDescriptor.OCTTREE, 2, null, null, null, null, null);
LookupTableJAI lut = (LookupTableJAI)op.getProperty("LUT");
IndexColorModel cm = new IndexColorModel(1, lut.getByteData()[0].length, lut.getByteData()[0], lut.getByteData()[1], lut.getByteData()[2]);
op = ErrorDiffusionDescriptor.create(surrogateImage, lut, KernelJAI.ERROR_FILTER_FLOYD_STEINBERG, null);
image = op.getAsBufferedImage();
Проблема в том, что image.getColorModel().getPixelSize()
возвращает 8, поэтому изображение сохраняется как растровое изображение 8bpp:
Размер этого изображения - 167 Кбайт.
Я где-то видел, что один из способов передачи цветовой модели для распространения ошибок - это установить подсказку рендеринга JAI.KEY_IMAGE_LAYOUT:
ImageLayout layout = new ImageLayout();
layout.setTileWidth(image.getWidth());
layout.setTileHeight(image.getHeight());
layout.setColorModel(cm);
layout.setSampleModel(op.getSampleModel());
RenderingHints rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
op = ErrorDiffusionDescriptor.create(surrogateImage, lut, KernelJAI.ERROR_FILTER_FLOYD_STEINBERG, rh);
image.getColorModel().getPixelSize()
теперь возвращает 1, но получившееся изображение значительно изменилось:
Однако размер этого изображения составляет 21 КиБ, примерно что, когда я использую MS Paint для преобразования образца изображения в монохромное растровое изображение. Итак, похоже, что BMPImageWriter
JAI использует правильную кодировку, но если вы внимательно посмотрите на второе изображение, соседние столбцы пикселей разделены на восемь пикселей. Фактически, вы можете видеть первое изображение, только каждый столбец пикселей из первого изображения расширяется до 8 столбцов пикселей.
Это ошибка в JAI? Могу ли я что-то сделать, чтобы свернуть эти столбцы пикселей шириной 8 в пиксели в один столбец?