I am trying to draw a RGB color wheel in Java, but I can't get the gradient by a circular shape. I just want to draw it on screen, with no user interaction at all.
This is all I have for now:
public void paint (Graphics g){
super.paint(g);
int red = 255;
int green = 0;
int blue = 0;
int x1 = 500;
int y1 = 305;
int x2 = 500;
int y2 = 50;
while (green != 255){
g.setColor(new Color(red, green, blue));
green++;
g.drawLine(x1, y1, x2, y2);
x2++;
if (y2 < y1){
y2++;
}
}
while (red != 0){
g.setColor(new Color(red, green, blue));
red--;
g.drawLine(x1, y1, x2, y2);
x2--;
y2++;
}
x2 = 500;
while (blue != 255){
g.setColor(new Color(red, green, blue));
blue++;
g.drawLine(x1, y1, x2, y2);
x2--;
if (y2 > y1){
y2--;
}
}
while (red != 255){
green--;
g.setColor(new Color(red, green, blue));
red++;
g.drawLine(x1, y1, x2, y2);
x2++;
y2--;
}
}
}
Which draws the gradient like this
This is what I want
Here is my solution for drawing a RGB Color Wheel in Java:
public class Main {
public static void main(String[] args) {
int rad = 1024;
BufferedImage img = new BufferedImage(rad, rad, BufferedImage.TYPE_INT_RGB);
// Center Point (MIDDLE, MIDDLE)
int centerX = img.getWidth() / 2;
int centerY = img.getHeight() / 2;
int radius = (img.getWidth() / 2) * (img.getWidth() / 2);
// Red Source is (RIGHT, MIDDLE)
int redX = img.getWidth();
int redY = img.getHeight() / 2;
int redRad = img.getWidth() * img.getWidth();
// Green Source is (LEFT, MIDDLE)
int greenX = 0;
int greenY = img.getHeight() / 2;
int greenRad = img.getWidth() * img.getWidth();
// Blue Source is (MIDDLE, BOTTOM)
int blueX = img.getWidth() / 2;
int blueY = img.getHeight();
int blueRad = img.getWidth() * img.getWidth();
for (int i = 0; i < img.getWidth(); i++) {
for (int j = 0; j < img.getHeight(); j++) {
int a = i - centerX;
int b = j - centerY;
int distance = a * a + b * b;
if (distance < radius) {
int rdx = i - redX;
int rdy = j - redY;
int redDist = (rdx * rdx + rdy * rdy);
int redVal = (int) (255 - ((redDist / (float) redRad) * 256));
int gdx = i - greenX;
int gdy = j - greenY;
int greenDist = (gdx * gdx + gdy * gdy);
int greenVal = (int) (255 - ((greenDist / (float) greenRad) * 256));
int bdx = i - blueX;
int bdy = j - blueY;
int blueDist = (bdx * bdx + bdy * bdy);
int blueVal = (int) (255 - ((blueDist / (float) blueRad) * 256));
Color c = new Color(redVal, greenVal, blueVal);
float hsbVals[] = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
Color highlight = Color.getHSBColor(hsbVals[0], hsbVals[1], 1);
img.setRGB(i, j, RGBtoHEX(highlight));
} else {
img.setRGB(i, j, 0xFFFFFF);
}
}
}
try {
ImageIO.write(img, "png", new File("wheel.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static int RGBtoHEX(Color color) {
String hex = Integer.toHexString(color.getRGB() & 0xffffff);
if (hex.length() < 6) {
if (hex.length() == 5)
hex = "0" + hex;
if (hex.length() == 4)
hex = "00" + hex;
if (hex.length() == 3)
hex = "000" + hex;
}
hex = "#" + hex;
return Integer.decode(hex);
}
}
From here , it seems like the easiest way to brighten a color is by converting it to HSB.
float hsbVals[] = Color.RGBtoHSB( originalColor.getRed(),
originalColor.getGreen(),
originalColor.getBlue(), null );
Color highlight = Color.getHSBColor( hsbVals[0], hsbVals[1],
0.5f * ( 1f + hsbVals[2] )); // Play with this part to modify rate of change
From what you have, it looks like you essentially need to erase all but a circular region in the middle.
From this answer , it seems like the Area class is easiest.
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g.create();
Rectangle2D rectangleNotToDrawIn = new Rectangle2D.Double(100, 100, 20, 30);
// You will need to find out what size ellipse you need
Area outside = calculateOutside(rectangleNotToDrawIn);
// draw color wheel here
g2.setPaint(Color.black); // assuming you want black
g2.setClip(outside);
g2.drawLine(0, 0, getWidth(), getHeight());
}
// Change this method to take in an ellipse shape.
private Area calculateOutside(Rectangle2D r) {
Area outside = new Area(new Rectangle2D.Double(0, 0, getWidth(), getHeight()));
outside.subtract(new Area(r));
return outside;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.