Trying to draw a vertical linear gradient using a map of colors, but only the first 9 colors are used: why?
(nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)
Summary
Context, Aim & Problem
What I have already tried
Pertinent sources explained
Expected results, Actual results & Question
Minimal, Complete, and Verifiable example
Context, Aim & Problem
I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.
At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1
, height
being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").
The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.
What I have already tried
I have a map of RGB values which defines a gradient.
The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.
So:
I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception
I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too
Pertinent sources explained
Calling methods to draw the gradient
The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.
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());
}
How I color pixels
I'm just iterating over the canvas.
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();
}
How do I find the index of the color of a pixel, within the list of colors?
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!");
}
Expected results, Actual results & Question
I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.
The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k
My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?
Minimal, Complete, and Verifiable example
Launcher.java
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());
}
}
}
Gui.java
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);
}
}
Colors.java
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();
}
}
FireColors.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));
}
}
java colors bufferedimage
add a comment |
(nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)
Summary
Context, Aim & Problem
What I have already tried
Pertinent sources explained
Expected results, Actual results & Question
Minimal, Complete, and Verifiable example
Context, Aim & Problem
I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.
At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1
, height
being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").
The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.
What I have already tried
I have a map of RGB values which defines a gradient.
The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.
So:
I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception
I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too
Pertinent sources explained
Calling methods to draw the gradient
The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.
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());
}
How I color pixels
I'm just iterating over the canvas.
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();
}
How do I find the index of the color of a pixel, within the list of colors?
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!");
}
Expected results, Actual results & Question
I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.
The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k
My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?
Minimal, Complete, and Verifiable example
Launcher.java
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());
}
}
}
Gui.java
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);
}
}
Colors.java
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();
}
}
FireColors.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));
}
}
java colors bufferedimage
add a comment |
(nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)
Summary
Context, Aim & Problem
What I have already tried
Pertinent sources explained
Expected results, Actual results & Question
Minimal, Complete, and Verifiable example
Context, Aim & Problem
I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.
At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1
, height
being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").
The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.
What I have already tried
I have a map of RGB values which defines a gradient.
The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.
So:
I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception
I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too
Pertinent sources explained
Calling methods to draw the gradient
The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.
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());
}
How I color pixels
I'm just iterating over the canvas.
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();
}
How do I find the index of the color of a pixel, within the list of colors?
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!");
}
Expected results, Actual results & Question
I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.
The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k
My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?
Minimal, Complete, and Verifiable example
Launcher.java
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());
}
}
}
Gui.java
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);
}
}
Colors.java
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();
}
}
FireColors.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));
}
}
java colors bufferedimage
(nota: a Minimal, Complete, and Verifiable example is provided at the end of this question)
Summary
Context, Aim & Problem
What I have already tried
Pertinent sources explained
Expected results, Actual results & Question
Minimal, Complete, and Verifiable example
Context, Aim & Problem
I am trying to animate some pixels to generate a fire animation in Java. Each pixel is colored so that a vertical linear gradient, from white to yellow, yellow to red, and red to black, is drawn. This gradient goes from bottom to top of the canvas.
At the beginning of the execution, all pixels are black, except the white line which is defined by the coordinate y = height - 1
, height
being the height of the canvas. This white line is used to init the gradient ("white to yellow, yellow to ..., etc.").
The problem is that the gradient begins correctly, but it stops when the 9th color is used. Then only this color is used to fill my gradient and I don't know why.
What I have already tried
I have a map of RGB values which defines a gradient.
The idea to know which color to apply to a pixel called "A" is to retrieve the RGB of the pixel just below it, then get the ID of this RGB among all the RGB of my map. Then, I get the RGB under this ID + 1 in this same map and apply it to the pixel A.
So:
I checked the function that returns the ID of the RGB, given this RGB: it seems to be OK since I don't have thrown any exception
I checked if the buffered image I use is correctly updated. In other words: if the fact that a pixel has been colored really has the consequence to determine the color of the pixel above : it's OK too
Pertinent sources explained
Calling methods to draw the gradient
The idea is to set all pixels in black, except the bottom line which is white. Then, I iterate on each canvas' pixel and give it the color of its below direct vertical neighbor. More precisely, I give it the color whose ID = the ID of this neighbor pixel's color + 1, within my map of colors.
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());
}
How I color pixels
I'm just iterating over the canvas.
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();
}
How do I find the index of the color of a pixel, within the list of colors?
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!");
}
Expected results, Actual results & Question
I expect to have several vertical gradients (each from bottom to top). "Several" because my canvas' height is greater than the number of the colors of my gradients and because I use a modulo to choose the color to apply.
The actual results are: I get a gradient that begins from white to yellow, there are only 9 colors and that's all. No orange, no red, no black. Indeed: https://imgur.com/oQFJ52k
My question is: since the good ID is retrieved, and the good neighbor chosen for a given pixel, why is my gradient blocked to the 9th color? In other words: why, from a precise moment, aren't the good colors chosen?
Minimal, Complete, and Verifiable example
Launcher.java
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());
}
}
}
Gui.java
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);
}
}
Colors.java
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();
}
}
FireColors.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));
}
}
java colors bufferedimage
java colors bufferedimage
asked Jan 1 at 14:55
JarsOfJam-SchedulerJarsOfJam-Scheduler
211315
211315
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Your problem is that FireColors
contains duplicate colors:
// 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!
The problem is together with your color selection algorithm:
// 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();
For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.
For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)
For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor()
returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)
To fix it, you should either redesign your color choosing algorithm or make your FireColor
colors unique.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996450%2ftrying-to-draw-a-vertical-linear-gradient-using-a-map-of-colors-but-only-the-fi%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your problem is that FireColors
contains duplicate colors:
// 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!
The problem is together with your color selection algorithm:
// 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();
For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.
For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)
For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor()
returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)
To fix it, you should either redesign your color choosing algorithm or make your FireColor
colors unique.
add a comment |
Your problem is that FireColors
contains duplicate colors:
// 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!
The problem is together with your color selection algorithm:
// 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();
For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.
For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)
For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor()
returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)
To fix it, you should either redesign your color choosing algorithm or make your FireColor
colors unique.
add a comment |
Your problem is that FireColors
contains duplicate colors:
// 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!
The problem is together with your color selection algorithm:
// 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();
For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.
For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)
For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor()
returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)
To fix it, you should either redesign your color choosing algorithm or make your FireColor
colors unique.
Your problem is that FireColors
contains duplicate colors:
// 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!
The problem is together with your color selection algorithm:
// 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();
For the 8th line, it reads the color from the line below it, finds its index (7), adds one and colors that line with the color #8.
For the 9th line, it reads the color from the line below it, finds its index (8), adds one and colors that line with the color #9 (which is the same as color #8)
For the 10th line, it reads the color from the line below it, finds its index (8, because getIndexOfColor()
returns the first found index, which is 8, not 9!), adds one and colors that line with the color #9 (which is the same as color #8)
To fix it, you should either redesign your color choosing algorithm or make your FireColor
colors unique.
answered Jan 1 at 19:51
Thomas KlägerThomas Kläger
6,6252818
6,6252818
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996450%2ftrying-to-draw-a-vertical-linear-gradient-using-a-map-of-colors-but-only-the-fi%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown