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

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

上面的代码使用颜色模型中定义的调色板生成具有 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:请注意,方法/类被命名为“hint”。

这可能不再是问题,但在过去,我经历过使用上面的提示禁用抖动不起作用。也不可能指定要使用的抖动算法,通常仅使用“有序”或“菱形”模式抖动。

因此,我为此实现了自己版本的各种抖动算法。请参阅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);

关于java - 使用自定义 ColorModel 减少颜色时 BufferedImage 禁用抖动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46852908/

相关文章:

java - 创建大型 BufferedImage 的更快方法

java - 缓冲图像 INT/4BYTE/USHORT

java - Graphics2D JPanel 显示但按钮不显示?

java - 为什么构造函数中 getHeight() 和 getWidth() 返回 0?我该如何避免这种情况?

java - 传递给 Paint() 调用的顶级组件是什么?

java - 当一周从星期一开始时,如何获取给定日期的星期几?

java - 取消投影鼠标以获取 3D 世界坐标 Libgdx

java - 将 array_walk 从 php 转换为 java 方法

java - 在 java 或 UE4 c++ 中获取三星 Galaxy S7 的真实屏幕分辨率

java - BufferedImage 旋转,改变结果背景