BufferedImage 在使用自定义 ColorModel 减少颜色时禁用抖动?

BufferedImage disable dithering when reducing color using custom ColorModel?

我正在使用自定义调色板(即自定义颜色模型)创建图像:

 BufferedImage img = new BufferedImage(orgImg.getWidth(), orgImg.getHeight(),
      BufferedImage.TYPE_BYTE_INDEXED,
      cm);
 Graphics2D g2 = img.createGraphics();
    g2.drawImage(orgImg, 0, 0, null);
    g2.dispose();

请注意,"cm" 变量是我的自定义颜色模型,具有 256 种颜色的调色板。

"orgImg" 变量是全彩色(24 大 argb)图像。

以上代码使用 colormodel 中定义的调色板生成具有 256 种颜色的 "orgImg" 副本。

效果很好。

但是 java 使用抖动来减少颜色。是否可以禁用此抖动?

请注意,我需要使用自己的调色板,以便最终图像匹配特定的调色板。

将图像绘制到 Graphics2D 对象时,可以使用 RenderingHint 控制渲染的各个方面。您应该能够使用 Graphics2D.setRenderingHintsetRenderingHints 方法禁用抖动,将 KEY_DITHERINGVALUE_DITHER_DISABLE 值作为参数传递:

Graphics2D g2 = img.createGraphics();
// Disable dithering
g2.setRenderingHint(RenderingHint.KEY_DITHERING, RenderingHint.VALUE_DITHER_DISABLE);
g2.drawImage(orgImg, 0, 0, null);
g2.dispose();

有关详细信息,请参阅 Java2D tutorial

PS:注意 methods/class 被命名为 "hint"。

这可能不再是问题,但在过去,我曾遇到过使用上述提示禁用抖动无效的情况。也无法指定要使用的抖动算法,通常只使用 "ordered" 或 "diamond" 模式抖动。

因此,我为此用途实现了自己的各种抖动算法版本。见 CopyDither (which does a closest match lookup for each pixel, probably what you want here) and DiffusionDither (which implements a "Floyd-Steinberg" error diffusion dither). Both of the mentioned implementations rely on a fast reverse lookup of color values. Unfortunately, the default IndexColorModel doesn't do fast reverse lookups. So I implemented a special class for this case too, see the InverseColorMapIndexColorModel class.

用法:

BufferedImage img = new BufferedImage(orgImg.getWidth(), orgImg.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, cm);
CopyDither noDither = new CopyDither(new InverseColorMapIndexColorModel(cm)); // cm must be IndexColorModel
noDither.filter(orgImg, img);