java - 按暗度递减顺序显示相同颜色的 n 个不同阴影的算法

标签 java algorithm colors rgb rgba

要求如下:

我们需要将值映射到颜色。所以每个离散值都会有一种颜色。

我们允许用户指定 maxColorNO minColor 但允许他们指定表示色度数的 bin 数。因此,如果选择的 maxColorColor.GREEN 并且 bins= 5 ,那么我们希望选择的颜色有 5 种绿色阴影因为最大是最暗的,其余四个将按亮度增加的顺序排列。

//Give me a list of 5 shades of Green with the first argument being the darkest.
List<Color> greenShades = calculateShades(Color.GREEN,5);

//Give me a list of 7 shades of RED with the first argument being the darkest.
List<Color> greenShades = calculateShades(Color.RED,7);

我在用 Java 编码时将问题标记为 Java。但我知道它只是一种算法。因此,用其他语言(如 JavaScript)实现此实现的实现/想法也是可以接受的。

最佳答案

基本概念围绕着基于源的一小部分生成颜色的想法......

也就是说,如果您想要 5 个波段,则每个波段的强度将是最后一个波段强度的 1/5...

public List<Color> getColorBands(Color color, int bands) {

    List<Color> colorBands = new ArrayList<>(bands);
    for (int index = 0; index < bands; index++) {
        colorBands.add(darken(color, (double) index / (double) bands));
    }
    return colorBands;

}

public static Color darken(Color color, double fraction) {

    int red = (int) Math.round(Math.max(0, color.getRed() - 255 * fraction));
    int green = (int) Math.round(Math.max(0, color.getGreen() - 255 * fraction));
    int blue = (int) Math.round(Math.max(0, color.getBlue() - 255 * fraction));

    int alpha = color.getAlpha();

    return new Color(red, green, blue, alpha);

}

作为一个快速而讨厌的例子......

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ColorBands {

    public static void main(String[] args) {
        new ColorBands();
    }

    public ColorBands() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JPanel bandsPane;
        private JSlider slider;
        private Timer changeTimer;

        public TestPane() {
            bandsPane = new JPanel(new GridBagLayout());
            slider = new JSlider(1, 100);
            setLayout(new BorderLayout());
            add(new JScrollPane(bandsPane));
            add(slider, BorderLayout.SOUTH);
            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    changeTimer.restart();
                }
            });

            changeTimer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int bands = slider.getValue();
                    List<Color> bandsList = getColorBands(Color.RED, bands);
                    bandsPane.removeAll();
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    gbc.insets = new Insets(1, 1, 1, 1);
                    for (Color color : bandsList) {
                        bandsPane.add(new ColorBand(color), gbc);
                    }
                    gbc.weighty = 1;
                    bandsPane.add(new JPanel(), gbc);
                    revalidate();
                    repaint();
                }
            });
            changeTimer.setRepeats(false);
            slider.setValue(1);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

    public List<Color> getColorBands(Color color, int bands) {

        List<Color> colorBands = new ArrayList<>(bands);
        for (int index = 0; index < bands; index++) {
            colorBands.add(darken(color, (double) index / (double) bands));
        }
        return colorBands;

    }

    public static Color darken(Color color, double fraction) {

        int red = (int) Math.round(Math.max(0, color.getRed() - 255 * fraction));
        int green = (int) Math.round(Math.max(0, color.getGreen() - 255 * fraction));
        int blue = (int) Math.round(Math.max(0, color.getBlue() - 255 * fraction));

        int alpha = color.getAlpha();

        return new Color(red, green, blue, alpha);

    }

    public class ColorBand extends JPanel {

        public ColorBand(Color color) {
            setBackground(color);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 20);
        }

    }

}

关于java - 按暗度递减顺序显示相同颜色的 n 个不同阴影的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18605410/

相关文章:

python - 生成所有可能的三连通图

algorithm - 是否有可能使 `foldrRanges` 与 `foldrRange2D` 一样快?

css - rgba 颜色代码渲染起来更重吗?

css - div 背景颜色,悬停时更改

java - 读取大文件的最有效方法

java - Java 中的对象检测/跟踪

java - 如何在二维字符数组中获取用户输入-java

java - gitignore 不会忽略已经提交的文件吗?

python - 改进元组距离计算算法以提高时间效率

opengl - 读取游戏(OpenGL 或 DirectX)屏幕上的像素