【发布时间】:2017-10-10 15:15:23
【问题描述】:
我正在尝试将图像仅转换为黑白(不是灰度)。
我用过这个:
BufferedImage blackAndWhiteImage = new BufferedImage(
dWidth.intValue(),
dHeight.intValue(),
BufferedImage.TYPE_BYTE_BINARY);
Graphics2D graphics = blackAndWhiteImage.createGraphics();
graphics.drawImage(colourImage, 0, 0, null);
return blackAndWhiteImage;
一切都很好,直到我决定尝试更亮的颜色,例如 Google 徽标:
结果是这样的:
然后我首先尝试使用:
BufferedImage blackAndWhiteImage2 = new BufferedImage(
dWidth.intValue(),
dHeight.intValue(),
BufferedImage.TYPE_USHORT_GRAY);
它似乎保存了蓝色,但不是最亮的(在本例中为黄色),并且您可能会看到它的质量有所下降:
非常感谢任何建议;我相信我正在寻找的是将除白色以外的所有颜色转换为黑色(这将是背景颜色),这在应用 TYPE_BYTE_BINARY 删除 alpha 通道时已经完成。
编辑: 可能我解释的不是很清楚:
- 最终图像必须具有白色背景 **1
- 所有其他颜色都必须转换为黑色
**1 - 在某些情况下,图像实际上是黑底白字..这很烦人 (whiteOnBlackExample),因为它使这个过程变得非常复杂,我稍后会离开,因为现在的优先级是转换“正常”图像。
我所做的是,首先去除 alpha 通道(如果存在) -> 因此将 alpha 通道转换为白色;然后将所有其他颜色转换为黑色
【问题讨论】:
-
问题是你只使用了黑色和白色,而不是灰色,所以明亮的颜色显示为白色。
-
见stackoverflow.com/questions/23980554/… 你也可以用黑色替换非白色像素
-
@StanislavL 遍历和操作像素似乎比内置方法慢。见stackoverflow.com/questions/34688182/…
-
您是仅限于 Swing/AWT 还是 JavaFX 是一种选择?
-
你肯定需要一个阈值可调的算法。一般来说,算法应该如下:
pixel(x, y) < threshold ? white : black。然后只需选择合适的阈值。由于您的原始像素是 RGB,您可能还需要将此值转换为适用的值以与阈值进行比较。有几种方法可以做到这一点: Lightness 方法:(max(R, G, B) + min(R, G, B)) / 2; 平均方法:(R + G + B) / 3; 亮度:0.21 * R + 0.72 * G + 0.07 * B