使用纯Java模仿JavaFX的ColorAdjust亮度 [英] Mimic JavaFX's ColorAdjust brightness using pure Java

查看:176
本文介绍了使用纯Java模仿JavaFX的ColorAdjust亮度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将彩色图像转换为可用的单色图像,但没有锯齿状的边缘。



来自类似问题






不需要:



解决方案

这是一种纯Java方法。无需Swing代码即可创建图像。而不是将图像更改为黑白,我们将图像更改为黑色和透明。这就是我们保留那些羽毛边缘的方式。



结果:



如果您想要真正的灰度没有alpha的图像,创建一个graphics2d对象,用所需的背景色填充它,然后在其上绘制图像。



关于将白色保留为白色,可以完成,但必须承认两件事之一。您要么放弃黑白方面,采用真实的灰度图像,要么保留黑白,但是得到锯齿状的边缘,白色的羽毛会变成任何其他颜色。发生这种情况的原因是,一旦我们命中了浅色像素,我们如何知道它是浅色特征还是白色与另一种颜色之间的过渡像素。我不知道一种无需边缘检测即可解决的方法。

 公共类Main {
private static void createAndShowGUI(){
//摇摆的东西
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame( Alpha Mask);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane()。setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS));

JLabel picLabel = new JLabel(new ImageIcon(getImg()));
frame.getContentPane()。add(picLabel);

BufferedImage alphaMask = createAlphaMask(getImg());

JLabel maskLabel = new JLabel(new ImageIcon(alphaMask));
frame.getContentPane()。add(maskLabel);

//显示窗口。
frame.pack();
frame.setVisible(true);
}

public static BufferedImage getImg(){
try {
return ImageIO.read(new URL( https://i.stack.imgur.com /UPmqE.png));
} catch(IOException e){
e.printStackTrace();
}
返回null;
}

public static BufferedImage createAlphaMask(BufferedImage img){
// TODO:如果您实际使用此
,请在此处复制img int width = img.getWidth( );
int [] data = new int [width];

for(int y = 0; y< img.getHeight(); y ++){
//如果argb数据
img.getRGB(0, y,宽度,1,数据,0、1);
for(int x = 0; x< width; x ++){
//将颜色数据设置为黑色,但保留alpha,这将防止出现粗糙边缘
int color = data [x ]& 0xFF000000;
data [x] =颜色;
}
img.setRGB(0,y,width,1,data,0,1);
}
返回img;
}

public static void main(String [] args){
javax.swing.SwingUtilities.invokeLater(()-> createAndShowGUI());
}
}


I'm attempting to convert a color image to a useable monochrome image, but without the "jagged" edges.

From a similar question asking to convert an image from color to black and white, one of the accepted answers provides a simple trick from JavaFX's ColorAdjust class using a setBrightness(-1) technique. This technique has the benefit of maintaining the soft edges between black and white, such as supporting a high-contrast theme without creating all-new icons set.

Note: I do understand the inaccuracy of the word "monochrome" here (some grayscaling will occur) but I'm not sure how else to describe this technique.

What's a way to mimic the ColorAdust technique using pure Java?

Desired:


NOT Desired:

解决方案

This is a pure Java approach. The Swing code is not needed to create the image. Instead of changing the image to black and white, we are changing the image to black and transparent. That is how we preserve those feathered edges.

result:

If you want a true grayscale image with no alpha, make a graphics2d object, fill it with the desired background color, then draw the image onto it.

As for preserving whites as white, this can be done, but one of two thing must be conceded. Either you give up the black and white aspect and adopt a true grayscale image, or you keep your black and white, but get a jagged edge where white feathers into any other color. This occurs because once we hit a light color pixel, how do we know whether it is a light colored feature, or a transition pixel between white and another color. I don't know of a way to fix that without edge detection.

public class Main {
    private static void createAndShowGUI() {
        //swing stuff
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("Alpha Mask");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));

        JLabel picLabel = new JLabel(new ImageIcon(getImg()));
        frame.getContentPane().add(picLabel);

        BufferedImage alphaMask = createAlphaMask(getImg());

        JLabel maskLabel = new JLabel(new ImageIcon(alphaMask));
        frame.getContentPane().add(maskLabel);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static BufferedImage getImg() {
        try {
            return ImageIO.read(new URL("https://i.stack.imgur.com/UPmqE.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static BufferedImage createAlphaMask(BufferedImage img) {
        //TODO: deep copy img here if you actually use this
        int width = img.getWidth();
        int[] data = new int[width];

        for (int y = 0; y < img.getHeight(); y++) {
            // pull down a line if argb data
            img.getRGB(0, y, width, 1, data, 0, 1);
            for (int x = 0; x < width; x++) {
                //set color data to black, but preserve alpha, this will prevent harsh edges
                int color = data[x] & 0xFF000000;
                data[x] = color;
            }
            img.setRGB(0, y, width, 1, data, 0, 1);
        }
        return img;
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(() -> createAndShowGUI());
    }
}

这篇关于使用纯Java模仿JavaFX的ColorAdjust亮度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆