Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.marginallyclever.donatello.colorspace;

/**
* Interface for color space conversion to and from RGB.
*/
public interface ColorSpace {
/**
* Converts RGB values (0-1 range) to the target color space.
* @param r Red component (0-1)
* @param g Green component (0-1)
* @param b Blue component (0-1)
* @return Array of converted color space values.
*/
float[] fromRGB(float r, float g, float b);

/**
* Converts from the target color space back to RGB (0-1 range).
* @param c1 First component of color space.
* @param c2 Second component of color space.
* @param c3 Third component of color space.
* @return Array with RGB values (0-1 range).
*/
float[] toRGB(float c1, float c2, float c3);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.marginallyclever.donatello.colorspace;

/**
* A color space that converts between RGB and HSV.
*/
public class HSVColorSpace implements ColorSpace {
@Override
public float[] fromRGB(float r, float g, float b) {
float max = Math.max(r, Math.max(g, b));
float min = Math.min(r, Math.min(g, b));
float delta = max - min;

float h = 0f;
if (delta != 0) {
if (max == r) h = ((g - b) / delta) % 6;
else if (max == g) h = ((b - r) / delta) + 2;
else h = ((r - g) / delta) + 4;
h /= 6f;
if (h < 0) h += 1;
}

float s = (max == 0) ? 0 : (delta / max);
float v = max;
return new float[]{h, s, v};
}

@Override
public float[] toRGB(float h, float s, float v) {
float c = v * s;
float x = c * (1 - Math.abs((h * 6) % 2 - 1));
float m = v - c;

float r = 0, g = 0, b = 0;
int sector = (int)(h * 6) % 6;
switch (sector) {
case 0: r = c; g = x; break;
case 1: r = x; g = c; break;
case 2: g = c; b = x; break;
case 3: g = x; b = c; break;
case 4: r = x; b = c; break;
case 5: r = c; b = x; break;
}
return new float[]{r + m, g + m, b + m};
}

@Override
public String toString() {
return "HSV";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.marginallyclever.donatello.colorspace;

/**
* LUV color space conversion.
* https://framewave.sourceforge.net/Manual/fw_function_020_0060_00330.html
* preserve the D65 white point.
*/
public class LUVColorSpace implements ColorSpace {
@Override
public float[] fromRGB(float r, float g, float b) {
float x = r * 0.4124564f + g * 0.3575761f + b * 0.1804375f;
float y = r * 0.2126729f + g * 0.7151522f + b * 0.0721750f;
float z = r * 0.0193339f + g * 0.1191920f + b * 0.9503041f;
return new float[]{x,y,z};
}

@Override
public float[] toRGB(float x, float y, float z) {
float r = x * 3.2404542f + y * -1.5371385f + z * -0.4985314f;
float g = x * -0.9692660f + y * 1.8760108f + z * 0.0415560f;
float b = x * 0.0556434f + y * -0.2040259f + z * 1.0572252f;
return new float[]{r,g,b};
}

@Override
public String toString() {
return "LUV";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.marginallyclever.donatello.colorspace;

/**
* A color space that converts between RGB and RGB.
*/
public class RGBColorSpace implements ColorSpace {
@Override
public float[] fromRGB(float r, float g, float b) {
return new float[]{r, g, b};
}

@Override
public float[] toRGB(float c1, float c2, float c3) {
return new float[]{c1, c2, c3};
}

@Override
public String toString() {
return "RGB";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@
public class CurveEditor extends JPanel {
private static class ControlPoint {
Point2d position;
Point2d tangentIn;
Point2d tangentOut;
// TODO add bezier curve control points

public ControlPoint(Point2d position) {
this.position = position;
this.tangentIn = new Point2d();
this.tangentOut = new Point2d();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.marginallyclever.donatello.colorspace;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class ColorSpaceTest {
@Test
public void testToAndFromRGB() {
testToAndFrom(new RGBColorSpace());
}

@Test
public void testToAndFromLUT() {
testToAndFrom(new LUVColorSpace());
}

@Test
public void testToAndFromHSV() {
testToAndFrom(new HSVColorSpace());
}

private void testToAndFrom(ColorSpace colorSpace) {
for (int r = 0; r < 256; r++) {
for (int g = 0; g < 256; g++) {
for (int b = 0; b < 256; b++) {
float r2 = r / 255f;
float g2 = g / 255f;
float b2 = b / 255f;
float[] converted = colorSpace.fromRGB(r2, g2, b2);
float[] after = colorSpace.toRGB(converted[0], converted[1], converted[2]);
Assertions.assertEquals(after[0], r2, 0.01, r+","+g+","+b);
Assertions.assertEquals(after[1], g2, 0.01, r+","+g+","+b);
Assertions.assertEquals(after[2], b2, 0.01, r+","+g+","+b);
}
}
}
}
}