Beatmup Java package
Color.java
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 package Beatmup.Imaging;
20 
21 /**
22  * Integer RGBA color value
23  */
24 public class Color {
25  public int r; //!< red
26  public int g; //!< green
27  public int b; //!< blue
28  public int a; //!< alpha
29 
30  /**
31  * Creates a zero-valued color.
32  */
33  public Color() {
34  r = g = b = a = 0;
35  }
36 
37  /**
38  * Creates a color by aggregating the four channels values components
39  * @param r the red channel value
40  * @param g the green channel value
41  * @param b the blue channel value
42  * @param a the alpha channel value
43  */
44  public Color(int r, int g, int b, int a) {
45  this.r = r;
46  this.g = g;
47  this.b = b;
48  this.a = a;
49  // This constructor is called by JNI, do not remove it.
50  }
51 
52  /**
53  * Constructs a color from its integer code.
54  * @param code The integer code.
55  */
56  public Color(int code) {
57  b = code % 256;
58  g = (code >> 8) % 256;
59  r = (code >> 16) % 256;
60  a = (code >> 24) % 256;
61  }
62 
63  /**
64  * @return the integer code of the current color.
65  */
66  public int getRgbaCode() {
67  return r | g << 8 | b << 16 | a << 24;
68  }
69 
70  /**
71  * Builds a color from a string.
72  * Accepts hexadecimal RGB and RGBA notations like "7f7f7f", "7f7f7fFF" (case-insensitive) and a comma-separed list of 3 or 4 decimal integer values like "127,127,127,255".
73  * @param expr The string expression
74  * @return the corresponding color. If cannot parsem throws an exception.
75  */
76  public static Color parseString(String expr) throws IllegalArgumentException {
77  // hex notation
78  if (expr.matches("(\\d|[a-fA-F]){6}")) {
79  Color c = new Color(Integer.parseInt(expr, 16));
80  c.a = 255;
81  return c;
82  }
83  if (expr.matches("(\\d|[a-fA-F]){8}"))
84  return new Color(Integer.parseInt(expr, 16));
85  // comma split notation
86  String vals[] = expr.split(",");
87  if (vals.length != 3 && vals.length != 4)
88  throw new IllegalArgumentException("Cannot parse color from expression '" +expr+ "'");
89  return new Color(
90  Integer.parseInt(vals[0]),
91  Integer.parseInt(vals[1]),
92  Integer.parseInt(vals[2]),
93  vals.length > 3 ? Integer.parseInt(vals[3]) : 255
94  );
95  }
96 
97  /**
98  * Returns a scaled version of the current color by given factors.
99  * @param factorRGB The color components scaling factor
100  * @param factorAlpha The alpha component scaling factor
101  * @return the scaled color value. The current instance of Color is not changed.
102  */
103  public Color scale(float factorRGB, float factorAlpha) {
104  return new Color(
105  Math.round(r * factorRGB),
106  Math.round(g * factorRGB),
107  Math.round(b * factorRGB),
108  Math.round(a * factorAlpha)
109  );
110  }
111 
112  /**
113  * Returns a fully saturated color from its hue.
114  * @param hueDegrees The hue in degrees.
115  * @return the color having the given hue.
116  */
117  public static Color byHue(float hueDegrees) {
118  final double
119  SQRT3 = 1.732050807568877,
120  hue = Math.toRadians(hueDegrees),
121  r = Math.max(0, (2 * Math.cos(hue) + 1) / 3),
122  g = Math.max(0, (SQRT3 * Math.sin(hue) - Math.cos(hue) + 1) / 3),
123  b = Math.max(0, (1 - SQRT3 * Math.sin(hue) - Math.cos(hue)) / 3),
124  norm = Math.max(r, Math.max(g, b));
125  return new Color(
126  (int) Math.floor(255 * r / norm),
127  (int) Math.floor(255 * g / norm),
128  (int) Math.floor(255 * b / norm),
129  255
130  );
131  }
132 
133  /**
134  * Predefined color constants.
135  */
136  public static final Color
137  TRANSPARENT_BLACK = new Color(0, 0, 0, 0),
138  BLACK = new Color(0, 0, 0, 255),
139  WHITE = new Color(255, 255, 255, 255),
140  RED = new Color(255, 0, 0, 255),
141  GREEN = new Color(0, 255, 0, 255),
142  BLUE = new Color(0, 0, 255, 255),
143  YELLOW = new Color(255, 255, 0, 255),
144  PURPLE = new Color(255, 0, 255, 255),
145  ORANGE = new Color(255, 127, 0, 255),
146  GRAY = new Color(127, 127, 127, 255),
147 
148  FECAMP_SKY = new Color(100, 140, 189, 255); // sky color in fecamp.bmp
149 }
Integer RGBA color value.
Definition: Color.java:24
static Color byHue(float hueDegrees)
Returns a fully saturated color from its hue.
Definition: Color.java:117
Color()
Creates a zero-valued color.
Definition: Color.java:33
Color scale(float factorRGB, float factorAlpha)
Returns a scaled version of the current color by given factors.
Definition: Color.java:103
Color(int code)
Constructs a color from its integer code.
Definition: Color.java:56
static Color parseString(String expr)
Builds a color from a string.
Definition: Color.java:76
Color(int r, int g, int b, int a)
Creates a color by aggregating the four channels values components.
Definition: Color.java:44
static final Color TRANSPARENT_BLACK
Predefined color constants.
Definition: Color.java:137