2017-10-20 82 views
0

我创建一个自定义调色板图像(即自定义的ColorModel):使用自定义ColorModel减少颜色时,BufferedImage会禁用抖动?

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

注意“厘米”变量是256个色调色板中的我的自定义的ColorModel。

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

上述代码使用colormodel中定义的调色板生成256色“orgImg”的副本。

这很好。

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

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

回答

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

使用的RenderingHints在这种特殊情况下无法正常工作(在其他/大多数情况下,它的工作),该KEY_DITHERING被忽略。互联网上有几个关于这个问题的话题,但没有一个提出了一个性能良好的解决方案。试试吧。 –

+1

我刚刚看到你编辑了你的问题;-)我会看看你的课程,他们看起来不错,因为使用对性能有好处的栅格。我会让你保持最新! –

+0

Cheers @haraldK,今天早上花了一些时间来解决问题,但在找到你的Maven依赖关系之后,一切都顺利进行。我将CopyDither与我的颜色模型一起使用,并生成了未添加的版本。而且速度也非常快,我的黑客setRgb(getRgb)对于每个像素来说都慢了50%。再次感谢! –