📄 color.java
字号:
package org.sunflow.image;
import org.sunflow.math.MathUtils;
public final class Color {
private float r, g, b;
public static final Color BLACK = new Color(0, 0, 0);
public static final Color WHITE = new Color(1, 1, 1);
public static final Color RED = new Color(1, 0, 0);
public static final Color GREEN = new Color(0, 1, 0);
public static final Color BLUE = new Color(0, 0, 1);
public static final Color YELLOW = new Color(1, 1, 0);
public static final Color CYAN = new Color(0, 1, 1);
public static final Color MAGENTA = new Color(1, 0, 1);
public static final Color GRAY = new Color(0.5f, 0.5f, 0.5f);
public static Color black() {
return new Color();
}
public static Color white() {
return new Color(1, 1, 1);
}
private static final float[] EXPONENT = new float[256];
static {
EXPONENT[0] = 0;
for (int i = 1; i < 256; i++) {
float f = 1.0f;
int e = i - (128 + 8);
if (e > 0)
for (int j = 0; j < e; j++)
f *= 2.0f;
else
for (int j = 0; j < -e; j++)
f *= 0.5f;
EXPONENT[i] = f;
}
}
public Color() {
}
public Color(float gray) {
r = g = b = gray;
}
public Color(float r, float g, float b) {
this.r = r;
this.g = g;
this.b = b;
}
public Color toNonLinear() {
r = RGBSpace.SRGB.gammaCorrect(r);
g = RGBSpace.SRGB.gammaCorrect(g);
b = RGBSpace.SRGB.gammaCorrect(b);
return this;
}
public Color toLinear() {
r = RGBSpace.SRGB.ungammaCorrect(r);
g = RGBSpace.SRGB.ungammaCorrect(g);
b = RGBSpace.SRGB.ungammaCorrect(b);
return this;
}
public Color(Color c) {
r = c.r;
g = c.g;
b = c.b;
}
public Color(int rgb) {
r = ((rgb >> 16) & 0xFF) / 255.0f;
g = ((rgb >> 8) & 0xFF) / 255.0f;
b = (rgb & 0xFF) / 255.0f;
}
public Color copy() {
return new Color(this);
}
public final Color set(float r, float g, float b) {
this.r = r;
this.g = g;
this.b = b;
return this;
}
public final Color set(Color c) {
r = c.r;
g = c.g;
b = c.b;
return this;
}
public final Color setRGB(int rgb) {
r = ((rgb >> 16) & 0xFF) / 255.0f;
g = ((rgb >> 8) & 0xFF) / 255.0f;
b = (rgb & 0xFF) / 255.0f;
return this;
}
public final Color setRGBE(int rgbe) {
float f = EXPONENT[rgbe & 0xFF];
r = f * ((rgbe >>> 24) + 0.5f);
g = f * (((rgbe >> 16) & 0xFF) + 0.5f);
b = f * (((rgbe >> 8) & 0xFF) + 0.5f);
return this;
}
public final boolean isBlack() {
return r <= 0 && g <= 0 && b <= 0;
}
public final float getLuminance() {
return (0.2989f * r) + (0.5866f * g) + (0.1145f * b);
}
public final float getMin() {
return MathUtils.min(r, g, b);
}
public final float getMax() {
return MathUtils.max(r, g, b);
}
public final float getAverage() {
return (r + g + b) / 3.0f;
}
public final float[] getRGB() {
return new float[] { r, g, b };
}
public final int toRGB() {
int ir = (int) (r * 255 + 0.5);
int ig = (int) (g * 255 + 0.5);
int ib = (int) (b * 255 + 0.5);
ir = MathUtils.clamp(ir, 0, 255);
ig = MathUtils.clamp(ig, 0, 255);
ib = MathUtils.clamp(ib, 0, 255);
return (ir << 16) | (ig << 8) | ib;
}
public final int toRGBE() {
// encode the color into 32bits while preserving HDR using Ward's RGBE
// technique
float v = MathUtils.max(r, g, b);
if (v < 1e-32f)
return 0;
// get mantissa and exponent
float m = v;
int e = 0;
if (v > 1.0f) {
while (m > 1.0f) {
m *= 0.5f;
e++;
}
} else if (v <= 0.5f) {
while (m <= 0.5f) {
m *= 2.0f;
e--;
}
}
v = (m * 255.0f) / v;
int c = (e + 128);
c |= ((int) (r * v) << 24);
c |= ((int) (g * v) << 16);
c |= ((int) (b * v) << 8);
return c;
}
public final Color constrainRGB() {
// clamp the RGB value to a representable value
float w = -MathUtils.min(0, r, g, b);
if (w > 0) {
r += w;
g += w;
b += w;
}
return this;
}
public final boolean isNan() {
return Float.isNaN(r) || Float.isNaN(g) || Float.isNaN(b);
}
public final boolean isInf() {
return Float.isInfinite(r) || Float.isInfinite(g) || Float.isInfinite(b);
}
public final Color add(Color c) {
r += c.r;
g += c.g;
b += c.b;
return this;
}
public static final Color add(Color c1, Color c2) {
return Color.add(c1, c2, new Color());
}
public static final Color add(Color c1, Color c2, Color dest) {
dest.r = c1.r + c2.r;
dest.g = c1.g + c2.g;
dest.b = c1.b + c2.b;
return dest;
}
public final Color madd(float s, Color c) {
r += (s * c.r);
g += (s * c.g);
b += (s * c.b);
return this;
}
public final Color madd(Color s, Color c) {
r += s.r * c.r;
g += s.g * c.g;
b += s.b * c.b;
return this;
}
public final Color sub(Color c) {
r -= c.r;
g -= c.g;
b -= c.b;
return this;
}
public static final Color sub(Color c1, Color c2) {
return Color.sub(c1, c2, new Color());
}
public static final Color sub(Color c1, Color c2, Color dest) {
dest.r = c1.r - c2.r;
dest.g = c1.g - c2.g;
dest.b = c1.b - c2.b;
return dest;
}
public final Color mul(Color c) {
r *= c.r;
g *= c.g;
b *= c.b;
return this;
}
public static final Color mul(Color c1, Color c2) {
return Color.mul(c1, c2, new Color());
}
public static final Color mul(Color c1, Color c2, Color dest) {
dest.r = c1.r * c2.r;
dest.g = c1.g * c2.g;
dest.b = c1.b * c2.b;
return dest;
}
public final Color mul(float s) {
r *= s;
g *= s;
b *= s;
return this;
}
public static final Color mul(float s, Color c) {
return Color.mul(s, c, new Color());
}
public static final Color mul(float s, Color c, Color dest) {
dest.r = s * c.r;
dest.g = s * c.g;
dest.b = s * c.b;
return dest;
}
public final Color div(Color c) {
r /= c.r;
g /= c.g;
b /= c.b;
return this;
}
public static final Color div(Color c1, Color c2) {
return Color.div(c1, c2, new Color());
}
public static final Color div(Color c1, Color c2, Color dest) {
dest.r = c1.r / c2.r;
dest.g = c1.g / c2.g;
dest.b = c1.b / c2.b;
return dest;
}
public final Color exp() {
r = (float) Math.exp(r);
g = (float) Math.exp(g);
b = (float) Math.exp(b);
return this;
}
public final Color opposite() {
r = 1 - r;
g = 1 - g;
b = 1 - b;
return this;
}
public final Color clamp(float min, float max) {
r = MathUtils.clamp(r, min, max);
g = MathUtils.clamp(r, min, max);
b = MathUtils.clamp(r, min, max);
return this;
}
public static final Color blend(Color c1, Color c2, float b) {
return blend(c1, c2, b, new Color());
}
public static final Color blend(Color c1, Color c2, float b, Color dest) {
dest.r = (1.0f - b) * c1.r + b * c2.r;
dest.g = (1.0f - b) * c1.g + b * c2.g;
dest.b = (1.0f - b) * c1.b + b * c2.b;
return dest;
}
public static final Color blend(Color c1, Color c2, Color b) {
return blend(c1, c2, b, new Color());
}
public static final Color blend(Color c1, Color c2, Color b, Color dest) {
dest.r = (1.0f - b.r) * c1.r + b.r * c2.r;
dest.g = (1.0f - b.g) * c1.g + b.g * c2.g;
dest.b = (1.0f - b.b) * c1.b + b.b * c2.b;
return dest;
}
public static final boolean hasContrast(Color c1, Color c2, float thresh) {
if (Math.abs(c1.r - c2.r) / (c1.r + c2.r) > thresh)
return true;
if (Math.abs(c1.g - c2.g) / (c1.g + c2.g) > thresh)
return true;
if (Math.abs(c1.b - c2.b) / (c1.b + c2.b) > thresh)
return true;
return false;
}
public String toString() {
return String.format("(%.3f, %.3f, %.3f)", r, g, b);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -