Имитация яркости ColorAdjust JavaFX с использованием чистой Java - PullRequest
3 голосов
/ 02 июля 2019

Я пытаюсь преобразовать цветное изображение в используемое монохромное изображение, но без «зубчатых» краев.

Из аналогичного вопроса с просьбой преобразовать изображение из цветного в черно-белое, один из принятых ответов предоставляет простой трюк из класса ColorAdjust JavaFX с использованием техники setBrightness(-1).Преимущество этого метода заключается в поддержании мягких краев между черным и белым, например, , поддерживающих высококонтрастную тему, без создания совершенно нового набора иконок .

Примечание: Я понимаю неточность слова «монохромный» здесь (произойдет некоторое изменение оттенков серого), но я не уверен, как еще описать эту технику.

Как можно имитировать технику ColorAdust, используя чистыйJava?

Желаемый:

soft edges


НЕЖелаемый:

jagged edges

1 Ответ

1 голос
/ 03 июля 2019

Это чисто Java-подход.Код Swing не нужен для создания изображения.Вместо того, чтобы менять изображение на черно-белое, мы меняем изображение на черное и прозрачное.Так мы сохраняем эти пернатые края.

результат: enter image description here

Если вы хотите получить настоящее изображение в оттенках серого без альфа-канала, создайте объект graphics2d, залейте его желаемым цветом фона, затем нарисуйтеизображение на него.

Что касается сохранения белого как белого, это может быть сделано, но одну из двух вещей следует признать.Либо вы отказываетесь от черно-белого аспекта и принимаете истинное изображение в оттенках серого, либо вы сохраняете свое черно-белое изображение, но получаете зазубренный край, где белые перья переходят в любой другой цвет.Это происходит потому, что как только мы попадаем на пиксель светлого цвета, как мы узнаем, является ли это светлым элементом или пикселем перехода между белым и другим цветом.Я не знаю, как это исправить без обнаружения краев.

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