Отключить дизеринг для TYPE_BYTE_INDEXED BufferedImage

У меня есть 256-цветное изображение BufferedImage, на котором я хочу нарисовать другое изображение BufferedImage (> 256 цветов). Поведение Java по умолчанию заключается в сглаживании цветов, которые не могут быть представлены в модели с низким содержанием цветов. Я хочу отключить это (таким образом, выбрав следующий лучший цвет, доступный в низкоцветной модели), поэтому я попытался использовать RenderingHints, чтобы указать новое поведение рендеринга, но это не работает:

public BufferedImage filter(BufferedImage src) {
    BufferedImage convertedImage = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
    Graphics2D g2d = (Graphics2D) convertedImage.getGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
    g2d.drawImage(src, 0, 0, null);
    return convertedImage;
}

Идеи?

ОБНОВЛЕНИЕ:

Я решил проблему, отрисовав новое изображение попиксельно, что может быть не очень быстро, но работает. Подробности смотрите в моем ответе.


person Victor-Philipp Negoescu    schedule 21.03.2014    source источник
comment
С первого взгляда на код я бы сказал, что вам нужно установить любые подсказки рендеринга перед рисованием изображения. Но не совсем понятно, чего вы хотите достичь: что должно произойти с цветами, которые не могут быть представлены? Следует ли выбрать ближайший цвет? Это может быть сложно ...   -  person Marco13    schedule 21.03.2014
comment
Ах да, две строки «RenderingHint» изначально находились перед строкой «drawImage». Я поправил.   -  person Victor-Philipp Negoescu    schedule 21.03.2014
comment
@ Victor-PhilippNegoescu Вы должны опубликовать обновление как ответ на свой вопрос и пометить его как принятое. Вы получите бонусные баллы, и вопрос больше не будет отображаться в очереди без ответа. :-) PS: Хотел бы я знать, почему ваш исходный код не работает, но я видел ту же проблему раньше и в итоге получил аналогичный метод, который вы описываете.   -  person Harald K    schedule 22.03.2014
comment
@haraldK Спасибо, мне пришлось ждать не менее 8 часов после публикации вопросов, чтобы ответить на них самому.   -  person Victor-Philipp Negoescu    schedule 24.03.2014


Ответы (1)


Я решил проблему, отрисовав новое изображение попиксельно, что может быть не очень быстро, но работает:

public BufferedImage filter(BufferedImage src) {
    BufferedImage convertedImage = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
    for (int x = 0; x < src.getWidth(); x++) {
        for (int y = 0; y < src.getHeight(); y++) {
            convertedImage.setRGB(x, y, src.getRGB(x, y));
        }
    }
    return convertedImage;
}
person Victor-Philipp Negoescu    schedule 24.03.2014