使用纯 Java 模仿 JavaFX 的 ColorAdjust 亮度

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

从要求将图像从彩色转换为黑白的类似问题中,接受的答案之一提供了ColorAdjust使用setBrightness(-1)技术的 JavaFX 类中的简单技巧。这种技术的好处是保持黑色和白色之间的柔和边缘,例如支持高对比度主题而无需创建全新的图标集

注意:我确实理解这里“单色”这个词的不准确性(会出现一些灰度),但我不确定如何描述这种技术。

使用纯 Java模仿该技术的方法是什么ColorAdust

期望:

http://img3.mukewang.com/6400596c0001756f02720215.jpg

不需要:

http://img4.mukewang.com/6400597700016af602720215.jpg


UYOU
浏览 134回答 1
1回答

紫衣仙女

这是一种纯 Java 方法。创建图像不需要 Swing 代码。我们没有将图像更改为黑色和白色,而是将图像更改为黑色和透明。这就是我们如何保护那些羽毛状的边缘。如果你想要一个没有 alpha 的真正的灰度图像,制作一个 graphics2d 对象,用所需的背景颜色填充它,然后将图像绘制到它上面。至于将白人保留为白人,这是可以做到的,但必须承认两件事之一。要么放弃黑白方面并采用真正的灰度图像,要么保留黑白,但会出现锯齿状边缘,白色羽毛会融入任何其他颜色。发生这种情况是因为一旦我们击中浅色像素,我们如何知道它是浅色特征,还是白色和另一种颜色之间的过渡像素。我不知道有什么方法可以在没有边缘检测的情况下解决这个问题。public class Main {&nbsp; &nbsp; private static void createAndShowGUI() {&nbsp; &nbsp; &nbsp; &nbsp; //swing stuff&nbsp; &nbsp; &nbsp; &nbsp; JFrame.setDefaultLookAndFeelDecorated(true);&nbsp; &nbsp; &nbsp; &nbsp; JFrame frame = new JFrame("Alpha Mask");&nbsp; &nbsp; &nbsp; &nbsp; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));&nbsp; &nbsp; &nbsp; &nbsp; JLabel picLabel = new JLabel(new ImageIcon(getImg()));&nbsp; &nbsp; &nbsp; &nbsp; frame.getContentPane().add(picLabel);&nbsp; &nbsp; &nbsp; &nbsp; BufferedImage alphaMask = createAlphaMask(getImg());&nbsp; &nbsp; &nbsp; &nbsp; JLabel maskLabel = new JLabel(new ImageIcon(alphaMask));&nbsp; &nbsp; &nbsp; &nbsp; frame.getContentPane().add(maskLabel);&nbsp; &nbsp; &nbsp; &nbsp; //Display the window.&nbsp; &nbsp; &nbsp; &nbsp; frame.pack();&nbsp; &nbsp; &nbsp; &nbsp; frame.setVisible(true);&nbsp; &nbsp; }&nbsp; &nbsp; public static BufferedImage getImg() {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return ImageIO.read(new URL("https://i.stack.imgur.com/UPmqE.png"));&nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; public static BufferedImage createAlphaMask(BufferedImage img) {&nbsp; &nbsp; &nbsp; &nbsp; //TODO: deep copy img here if you actually use this&nbsp; &nbsp; &nbsp; &nbsp; int width = img.getWidth();&nbsp; &nbsp; &nbsp; &nbsp; int[] data = new int[width];&nbsp; &nbsp; &nbsp; &nbsp; for (int y = 0; y < img.getHeight(); y++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // pull down a line if argb data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img.getRGB(0, y, width, 1, data, 0, 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int x = 0; x < width; x++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //set color data to black, but preserve alpha, this will prevent harsh edges&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int color = data[x] & 0xFF000000;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data[x] = color;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img.setRGB(0, y, width, 1, data, 0, 1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return img;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; javax.swing.SwingUtilities.invokeLater(() -> createAndShowGUI());&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java