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

时间:2017-10-20 15:58:20

标签: java bufferedimage graphics2d dithering

我使用自定义调色板创建图像(换句话说是自定义颜色模型):

 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)图像。

以上代码会生成一份" orgImg" 256色,使用colormodel中定义的调色板。

这很好用。

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

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

1 个答案:

答案 0 :(得分:2)

将图像绘制到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:请注意,方法/类名为"提示"。

这可能不再是一个问题,但在过去我曾经历过使用上述提示禁用抖动不起作用。它也不可能指定要使用的抖动算法,通常只有"有序"或"钻石"使用模式抖动。

因此我为此用途实现了我自己的各种抖动算法版本。请参阅CopyDither(对每个像素进行最接近的匹配查找,可能是您想要的)和DiffusionDither(实现" Floyd-Steinberg"错误扩散抖动)。所提到的两种实现都依赖于颜色值的快速反向查找。不幸的是,默认IndexColorModel没有快速反向查找。所以我也为这个案例实现了一个特殊的类,请参阅InverseColorMapIndexColorModel类。

用法:

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);