Java - 将图像转换为黑白 - 失败,颜色鲜艳

467*_*3_j 7 java javafx image awt

我正在尝试将图像转换为仅黑白(不是灰度).

我用过这个:

BufferedImage blackAndWhiteImage = new BufferedImage(
        dWidth.intValue(),
        dHeight.intValue(),
        BufferedImage.TYPE_BYTE_BINARY);
Graphics2D graphics = blackAndWhiteImage.createGraphics();
graphics.drawImage(colourImage, 0, 0, null);

return blackAndWhiteImage;
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到我决定尝试更亮的颜色,例如Google徽标:

GOOGLELOGO

它出来了:

goolgeLogoBroken1

然后我首先尝试通过槽灰度使用:

BufferedImage blackAndWhiteImage2 = new BufferedImage(
        dWidth.intValue(),
        dHeight.intValue(),
        BufferedImage.TYPE_USHORT_GRAY);
Run Code Online (Sandbox Code Playgroud)

并且它似乎保存了蓝色,但不是最亮的(在这种情况下是黄色),并且您可能会看到它的质量下降:

goolgeLogoBroken1

任何建议都非常感谢; 我相信我所追求的是将每种颜色转换为黑色,除了白色(这将是背景颜色),这已经在应用TYPE_BYTE_BINARY去除alpha通道时完成.


编辑: 也许我没有解释清楚:

  • 最终图像必须具有白色背景**1
  • 每种其他颜色都必须转换为黑色

**1 - 在某些情况下,图像实际上是白色的黑色...这很烦人(whiteOnBlackExample),因为它使这个过程变得复杂很多,我将在稍后介绍,现在优先考虑转换"正常"图像.

我做的是,首先剥离alpha通道(如果它存在) - >因此将alpha通道转换为白色; 然后将每个其他颜色转换为黑色

use*_*551 5

如果您使用JavaFX,则可以使用(最小)ColorAdjust亮度的效果-1,这会使所有(非白色)颜色变为黑色:

public class Main extends Application {

    Image image = new Image("https://i.stack.imgur.com/UPmqE.png");

    @Override
    public void start(Stage primaryStage) {
        ImageView colorView = new ImageView(image);
        ImageView bhView = new ImageView(image);

        ColorAdjust colorAdjust = new ColorAdjust();
        colorAdjust.setBrightness(-1);
        bhView.setEffect(colorAdjust);

        primaryStage.setScene(new Scene(new VBox(colorView, bhView)));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这些Effect是经过优化的,因此它们可能比手动应用它们要快。

编辑

由于您的要求是

  1. 任何不透明的像素都应转换为白色,并且
  2. 任何非白色的像素都应转换为黑色,

就我所知,预先设计的效果不适合您-它们太具体了。您可以逐像素进行操作:

WritableImage writableImage = new WritableImage(image.getPixelReader(), (int) image.getWidth(), (int) image.getHeight());
PixelWriter pixelWriter = writableImage.getPixelWriter();
PixelReader pixelReader = writableImage.getPixelReader();
for (int i = 0; i < writableImage.getHeight(); i++) {
    for (int j = 0; j < writableImage.getWidth(); j++) {
        Color c = pixelReader.getColor(j, i);
        if (c.getOpacity() < 1) {
            pixelWriter.setColor(j, i, Color.WHITE);
        }
        if (c.getRed() > 0 || c.getGreen() > 0 || c.getBlue() > 0) {
            pixelWriter.setColor(j, i, Color.BLACK);
        }
    }
}
ImageView imageView = new ImageView(writableImage);
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

请注意,应用规则的顺序很重要。如果先应用1然后再应用2,则透明的非白色像素会变成白色,但是如果先应用2然后再应用1,它将最终变成黑色。这是因为预定义WHITEBLACK颜色是不透明的。您可以手动设置红色,绿色和蓝色值,而不必更改alpha值。这完全取决于您的确切要求。

请记住,由于某些文件格式的有损压缩,您可能根本无法在其中找到真白色,但是该值接近真白色,您的眼睛无法分辨出区别。