【问题标题】:BufferedImage is not changing the colour of all white parts of the imageBufferedImage 不会改变图像所有白色部分的颜色
【发布时间】:2016-04-27 04:35:59
【问题描述】:

我有一组黑白汉字字符图像,我正在尝试更改其颜色。我希望白色图像的所有白色部分(即不是字符的图像的所有部分)都变成特定的颜色。我正在使用 BufferedImages 执行此操作,方法是使用 for 循环遍历图像中的每个像素,检查它是否为白色,然后将白色更改为传递给该方法的颜色。以下是相关方法的代码:

public static void illuminateImage(BufferedImage elementImage, Color elementColor){
    for (int j = 0; j < elementImage.getWidth(); j++){
        for (int k = 0; k < elementImage.getHeight(); k++){
            if(elementImage.getRGB(j, k) == Color.WHITE.getRGB()){//images1.get(0).getRGB(0, 0)){
                elementImage.setRGB(j,k, elementColor.getRGB());
            }
        }
    }
}

问题在于并非每个白色像素都在改变颜色。当我调用该方法时,不是汉字字符的图像的所有部分都不会改变颜色。虽然大部分会改变颜色,但部分有一些白色斑块。为什么会出现这种情况?

我认为解决这个问题的方法是编写代码来检查像素是否不是黑色,然后将它们更改为给定的颜色。但是,这不起作用,只是将整个图像变成给定的颜色,我认为是因为字符不是严格的黑色,即使它们看起来很像。我不知道如何获得字符的颜色。任何帮助,将不胜感激。

【问题讨论】:

  • 很明显,图像中并非所有像素颜色都像黑色 (0,0,0) 和白色 (255,255,255) 一样简单。您需要考虑黑白范围或将每张图像中的像素修改为真正的黑白。

标签: java colors bufferedimage


【解决方案1】:

在我看来,你所有的“白色”都不完全是白色,而且你所有的黑色也不完全是黑色(根据你所说的)。

你应该做的是打印出汉字中的每一种颜色,看看发生了什么。

诸如此类的东西。

    public static void illuminateImage(BufferedImage elementImage, Color elementColor)
    {
        for (int j = 0; j < elementImage.getWidth(); j++)
        {
            for (int k = 0; k < elementImage.getHeight(); k++)
           {
              System.out.println(elementImage.getRGB(j, k));
           }
        }
    }

从那里你的选择是。

  1. 将所有内容更改为白色和黑色(不确定这些图像来自何处,但您应该将它们设置为正确的白色和黑色颜色,因此您必须使用 Photoshop 之类的程序对其进行编辑,或者使用代码亲自操作它们。

  2. 与其寻找颜色,不如寻找一系列颜色,或寻找色调,当然这对于白色/黑色阴影可能更困难。

IMO 我会查看 WHITE 的范围是什么,然后搜索整个范围以查看颜色是否在其中,即 200,200,200-255,255,255 以涵盖“白色”的所有可能性,但可能远远超出需要,所以检查一些颜色图表。

由于您的汉字应该是黑/白的,因此您在查找范围时应该没有问题,并且它会影响您应用程序的其余部分。

这个网站应该提供一些关于色度键控的有趣信息。

http://www.lac.inpe.br/JIPCookbook/6520-howto-chromakey.jsp

总体而言,您需要弄清楚其他像素是什么颜色,然后确定您是使用 Photoshop 等程序手动编辑它们,还是只是测试范围。

祝你好运。


查找 RGB 值的代码。

Color c = new Color(elementImage.getRGB(j, k));

  System.out.println(c.getRed() +  " | " + c.getGreen() + " | " + c.getBlue() );

要转换回整数,请查看您的值。

B 包含 0-7 位,G 是 8-15,R 是 16-24。

你会的 (2^16*Red) + (2^8 *Green) + (Blue) 再次获得整数值。


补充一点,我们发现 OP 使用的是 Alpha 通道,所以他的白色值为 -1,这是正确的。

所以 OP 只需要使用 RGB 值来确保他在一定的阈值内才能选择或不选择,而不是整数值,这将更难计算。

【讨论】:

  • 我有点困惑,因为您提供的值不是 RGB 值,对吧?我对如何找到白色的 RGB 范围感到困惑。
  • 我确实给了你 RGB 值 255 红色、255 绿色和 255 蓝色是白色。 0,0,0 为黑色。现在,在这种情况下,我们真的可以只获取红色绿色和蓝色的每个值,并检查它们是否都高于 200。所以我将在上面进行编辑。
  • 抱歉,我的意思是当您打印出 RGB 值时,它们会显示为一个整数,而不是三个。如何将该 RGB 代码转换为仅显示一个值的代码?
  • 例如,当我得到黑色的RGB时,它输出为1。它不会打印出三个整数。
  • 您的意思是指向您发送给我的那个网站的链接吗?我在那里找不到它从三个整数转换为一个的地方。
【解决方案2】:
   public static void illuminateImage(BufferedImage elementImage, Color elementColor)
    {
        for (int j = 0; j < elementImage.getWidth(); j++)
        {
            for (int k = 0; k < elementImage.getHeight(); k++)
           {
              Color c = new Color(elementImage.getRGB(j, k));
              c.getBlue();
              c.getGreen();
              c.getRed();
           }
        }
    }

public static void illuminateImage(BufferedImage elementImage, Color elementColor){
    int threshold = 300;//You can try other threshold
    for (int j = 0; j < elementImage.getWidth(); j++){
        for (int k = 0; k < elementImage.getHeight(); k++){
            if(elementImage.getRGB(j, k) >= (Color.WHITE.getRGB() + threshold)){//images1.get(0).getRGB(0, 0)){
                elementImage.setRGB(j,k, elementColor.getRGB());
            }
        }
    }
}

这样可以得到红绿蓝值

【讨论】:

  • 阈值很有用,但您需要将其分别应用于颜色分量(R、G、B)。只需将任意数字添加到打包的 ARGB 值,可能会导致一个或多个组件溢出,并且与预期颜色不匹配(而是一些其他非预期颜色)。
  • 是的,通过检查每个值是否高于 200 解决了该问题,但该值也可能发生变化。现在OP说它有效。我个人可能只是将所有内容更改为完全白色和黑色,但如果这适用于 OP,那么这就是最重要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多