本文介绍了Java-将图像转换为黑白-亮色失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to convert an image to black and white only (not grey scale).

我用过这个:

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徽标)

Everything fine, until I decided to try out brighter colors, like the Google logo for example:

结果是这样的:

然后我首先尝试使用以下方法通过低谷灰度:

Then I tried first to pass trough grey scale first using:

BufferedImage blackAndWhiteImage2 = new BufferedImage(
        dWidth.intValue(),
        dHeight.intValue(),
        BufferedImage.TYPE_USHORT_GRAY);

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

And it seemed to have saved the Blue color, but not the brightest (in this case yellow), and as you may see it decreased in quality:

任何建议都值得赞赏;我相信我要寻找的是将除白色(这将是背景色)以外的所有颜色转换为黑色,这在应用 TYPE_BYTE_BINARY 删除Alpha通道时已经完成.

Any suggestions are much appreciated; I believe what I am seeking for is to convert every colour to Black except White (which would be the background color), this is already done when applying TYPE_BYTE_BINARY removing the alpha channel.

也许我还没有解释得很清楚:

Maybe I have not explained very clear:

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

** 1-在某些情况下,图像实际上是黑底白字..这很烦人( whiteOnBlackExample ),因为它使此过程变得非常复杂,我将在稍后继续讨论,因为现在的重点是转换正常"图片.

**1 - there are some cases where the image is actually White on Black..which is annoying (whiteOnBlackExample) as it complicates a lot this process, and I will leave this later on, as priority now is to convert "normal" images.

我所做的是,如果存在Alpha通道,则首先将其去除->因此将Alpha通道转换为White;然后将其他所有颜色转换为黑色

What I did was, first strip out the alpha channel if it exists -> therefore convert the alpha channel to White; then convert every other color to Black

推荐答案

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

If you use JavaFX you can use the ColorAdjust effect with brightness of -1 (minimum), which makes all the (non-white) colors black:

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

这些 Effect s已优化,因此它们可能比手动应用它们要快.

These Effects are optimized so they are probably faster than what you would achieve by applying them manually.

修改

因为您的要求是

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

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

the predesigned effects won't suit you as far as I can tell - they are too specific. You can do pixel by pixel manipulation:

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

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

Note that the order in which you apply the rules matter. A transparent non-white pixel will turn white if you apply 1 and then 2, but if you apply 2 and then 1 it will end up black. This is because the predefined WHITE and BLACK colors are opaque. You can manually set the red, green and blue values while not changing the alpha value instead. It all depends on your exact requirements.

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

Remember that due to lossy compression of some file formats you might not find true white in them at all, but a value which is close to true white and your eye won't be able to tell the difference.

这篇关于Java-将图像转换为黑白-亮色失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 23:07