代码之家  ›  专栏  ›  技术社区  ›  JarsOfJam-Scheduler

尝试使用颜色图绘制垂直线性渐变,但只使用前9种颜色:为什么?

  •  0
  • JarsOfJam-Scheduler  · 技术社区  · 7 年前

    (注:本问题末尾提供了一个最小、完整和可验证的示例)

    总结

    1. 背景、目标和问题

    2. 我已经试过了

    3. 相关资料解释

    4. 预期结果、实际结果和问题

    5. 最小、完整和可验证的示例

    背景、目标和问题

    我试图动画一些像素,以生成一个在Java中的动画动画。每个像素的颜色都是垂直的线性渐变,从白色到黄色,黄色到红色,红色到黑色。这个渐变从画布的底部到顶部。

    在执行开始时,除了由坐标定义的白线之外,所有像素都是黑色的。 y = height - 1 , height 是画布的高度。此白线用于初始化渐变(“ 白变黄 ,黄色到……等)。

    问题是渐变开始正确,但当使用第9种颜色时,渐变停止。然后只有这个颜色被用来填充我的渐变,我不知道为什么。

    我已经试过了

    我有一个定义渐变的RGB值的映射。

    了解要应用于称为“A”的像素的颜色的想法是检索其正下方像素的RGB,然后在地图的所有RGB中获取该RGB的ID。然后,我在同一张地图中得到这个id+1下的RGB,并将它应用到像素A上。

    所以:

    1. 我检查了返回rgb ID的函数,给定这个rgb:看起来没问题,因为我没有抛出任何异常

    2. 我检查了我使用的缓冲图像是否正确更新。换言之:如果一个像素被着色的事实真的有决定上面像素颜色的结果:也可以。

    相关资料解释

    调用绘制渐变的方法

    其想法是将所有像素设置为黑色,除了底线是白色。然后,我迭代每一个画布的像素,并赋予它低于垂直邻域的颜色。更准确地说,我给它一种颜色,在我的颜色地图中,它的ID=这个相邻像素的颜色的ID+1。

        Colors colors = new FireColors(new ArrayList<>());
        gui.colorize(colors.getColorAtIndex(34), -1, -1);  // Setting black anywhere
        gui.colorize(colors.getColorAtIndex(0), -1, height - 1);  // Setting white, in a lower line
    
        try {
            for(int y = height - 2; y >= 0; y--) {
                for(int x = 0; x < width; x++) {
                    int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
                    int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
                    int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
                    gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
                }
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    

    如何为像素着色

    我只是在画布上迭代。

    void colorize(Color color, int x_parameter, int y_parameter) {
        for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
            for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
                buffered_image.setRGB(x, y, color.getRGB());
            }
        }
        panel.repaint();
    }
    

    如何在颜色列表中找到像素颜色的索引?

    int getIndexOfColor(int rgb) throws Exception {
        for (int x = 0; x < colors.size(); x++) {
            if(colors.get(x).getRGB() == rgb) {
                return x;
            }
        }
        throw new Exception("Color not found in the list!");
    }
    

    预期结果、实际结果和问题

    我希望有几个垂直梯度(每个从下到上)。”几个“因为我的画布的高度大于我的渐变颜色的数量,而且因为我使用一个模块来选择要应用的颜色。

    实际结果是:我得到了一个从白色到黄色的渐变,只有9种颜色,仅此而已。没有橙色,没有红色,没有黑色。的确: https://imgur.com/oQFJ52k

    我的问题是:既然检索到了好的ID,并且为一个给定的像素选择了好的邻居,为什么我的渐变被阻塞到第9种颜色?换言之:为什么从一个精确的时刻开始,不选择好的颜色?

    最小、完整和可验证的示例

    爪哇

    import java.util.ArrayList;
    
    public class Launcher {
    
        public static void main(String args[]) {
            int width = 150, height = 150;
            Gui gui = new Gui(width, height);
            gui.setUp("DOOM-like fire");
            gui.setVisible(true);
    
            Colors colors = new FireColors(new ArrayList<>());
            gui.colorize(colors.getColorAtIndex(34), -1, -1);  // Setting black anywhere
            gui.colorize(colors.getColorAtIndex(0), -1, height - 1);  // Setting white, in a lower line
    
            try {
                for(int y = height - 2; y >= 0; y--) {
                    for(int x = 0; x < width; x++) {
                        int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
                        int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
                        int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
                        gui.colorize(colors.getColorAtIndex(index_of_color_to_apply), x, y);
                    }
                }
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
    
    }
    

    爪哇

    import java.awt.*;
    import javax.swing.*;
    import java.awt.image.BufferedImage;
    
    class Gui extends JFrame {
    
        private JPanel panel;
        private BufferedImage buffered_image;
    
        Gui(int width, int height) {
            buffered_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            panel = new JPanel() {
                public void paintComponent(Graphics graphics) {
                    super.paintComponent(graphics);
                    graphics.drawImage(buffered_image, 0, 0, null);
                }
            };
        }
    
        void setUp(String title) {
            setTitle(title);
            setLayout(null);
            setSize(buffered_image.getWidth(), buffered_image.getHeight());
            setContentPane(panel);
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    
        void colorize(Color color, int x_parameter, int y_parameter) {
            for(int y = (y_parameter == -1 ? 0 : y_parameter); y <= (y_parameter == -1 ? this.getHeight() - 1 : y_parameter); y++) {
                for(int x = (x_parameter == -1 ? 0 : x_parameter); x <= (x_parameter== -1 ? this.getWidth() - 1 : x_parameter); x++) {
                    buffered_image.setRGB(x, y, color.getRGB());
                }
            }
            panel.repaint();
        }
    
        int getRGBAtCoordinates(int x, int y) {
            return buffered_image.getRGB(x, y);
        }
    
    }
    

    爪哇

    import java.awt.Color;
    import java.util.List;
    
    abstract class Colors {
        List<Color> colors;
    
        Color getColorAtIndex(int index) {
            return colors.get(index);
        }
    
        int getIndexOfColor(int rgb) throws Exception {
            for (int x = 0; x < colors.size(); x++) {
                if(colors.get(x).getRGB() == rgb) {
                    return x;
                }
            }
            throw new Exception("Color not found in the list!");
        }
    
        int getSize() {
            return colors.size();
        }
    }
    

    FielLo.java

    import java.awt.Color;
    import java.util.List;
    
    class FireColors extends Colors {
    
        FireColors(List<Color> colors) {
    
            this.colors = colors;
    
            this.colors.add(new Color(255, 255, 255));
            this.colors.add(new Color(239, 239, 199));
            this.colors.add(new Color(223, 223, 159));
            this.colors.add(new Color(207, 207, 111));
            this.colors.add(new Color(183, 183, 55));
            this.colors.add(new Color(183, 183, 47));
            this.colors.add(new Color(183, 175, 47));
            this.colors.add(new Color(191, 175, 47));
            this.colors.add(new Color(191, 167, 39));
            this.colors.add(new Color(191, 167, 39));
            this.colors.add(new Color(191, 159, 31));
            this.colors.add(new Color(191, 159, 31));
            this.colors.add(new Color(199, 151, 31));
            this.colors.add(new Color(199, 143, 23));
            this.colors.add(new Color(199, 135, 23));
            this.colors.add(new Color(207, 135, 23));
            this.colors.add(new Color(207, 127, 15));
            this.colors.add(new Color(207, 119, 15));
            this.colors.add(new Color(207, 111, 15));
            this.colors.add(new Color(215, 103, 15));
            this.colors.add(new Color(215, 95, 7));
            this.colors.add(new Color(223, 87, 7));
            this.colors.add(new Color(223, 87, 7));
            this.colors.add(new Color(223, 79, 7));
            this.colors.add(new Color(199, 71, 7));
            this.colors.add(new Color(191, 71, 7));
            this.colors.add(new Color(175, 63, 7));
            this.colors.add(new Color(159, 47, 7));
            this.colors.add(new Color(143, 39, 7));
            this.colors.add(new Color(119, 31, 7));
            this.colors.add(new Color(103, 31, 7));
            this.colors.add(new Color(87, 23, 7));
            this.colors.add(new Color(71, 15, 7));
            this.colors.add(new Color(47, 15, 7));
            this.colors.add(new Color(7, 7, 7));
    
        }
    
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Thomas Kläger    7 年前

    你的问题是 FireColors 包含重复颜色:

    // FireColors, lines 20 and 21:
    this.colors.add(new Color(191, 167, 39));
    this.colors.add(new Color(191, 167, 39));
    // more duplicate colors found later on!
    

    问题与您的颜色选择算法一起出现:

    // Launcher lines 20 to 22:
    int below_pixel_rgb = gui.getRGBAtCoordinates(x, y + 1);
    int index_of_found_color = colors.getIndexOfColor(below_pixel_rgb);
    int index_of_color_to_apply = (index_of_found_color + 1) % colors.getSize();
    

    对于第8行,它从下面的行中读取颜色,找到其索引(7),添加一个和颜色8对齐的颜色。

    对于第9行,它从下面的行中读取颜色,找到其索引(8),添加一个颜色,并添加与颜色9(与颜色8相同)对齐的颜色。

    对于第10行,它从下面的行中读取颜色,找到其索引(8,因为 getIndexOfColor() 返回找到的第一个索引,它是8,而不是9!),添加一个颜色和与颜色9(与颜色8相同)对齐的颜色。

    要修复它,您应该重新设计颜色选择算法或使 FireColor 色彩独特。

    推荐文章