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.setRenderingHint
或 setRenderingHints
方法禁用抖动,将 KEY_DITHERING
和 VALUE_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);
我正在使用自定义调色板(即自定义颜色模型)创建图像:
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.setRenderingHint
或 setRenderingHints
方法禁用抖动,将 KEY_DITHERING
和 VALUE_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);