Created
October 3, 2016 22:10
-
-
Save hageldave/b6ad662a475474fdcf04af816b4b31ed to your computer and use it in GitHub Desktop.
demo app showing the RGB representable colors of LAB
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static void main(String[] args) throws IOException { | |
Img[] gammut = new Img[256]; | |
Consumer<Pixel> lab2rgb = (px)->{px.setValue(transformLAB2RGB(px.getValue()));}; | |
for(int l = 0; l < 256; l++){ | |
int L = l; | |
Img img = new Img(256, 256); | |
img.forEach(px->{px.setRGB(L, px.getX(), px.getY());}); | |
img.forEach(lab2rgb); | |
gammut[l] = img; | |
} | |
int[] current = {0}; | |
ImageFrame frame = new ImageFrame(); | |
frame.setTitle("L="+current[0]); | |
ImagePanel panel = frame.getPanel(); | |
panel.setImg(gammut[current[0]]); | |
panel.addMouseWheelListener(e->{ | |
int plus = e.getWheelRotation(); | |
current[0] = (current[0] + 256 + plus) % 256; | |
panel.setImg(gammut[current[0]]); | |
frame.setTitle("L="+current[0]); | |
}); | |
panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP"); | |
panel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN"); | |
panel.getActionMap().put("UP", new AbstractAction() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
current[0] = (current[0] + 256 + 1) % 256; | |
panel.setImg(gammut[current[0]]); | |
frame.setTitle("L="+current[0]); | |
} | |
}); | |
panel.getActionMap().put("DOWN", new AbstractAction() { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
current[0] = (current[0] + 256 -1) % 256; | |
panel.setImg(gammut[current[0]]); | |
frame.setTitle("L="+current[0]); | |
} | |
}); | |
frame.setVisible(true); | |
} | |
static int transformLAB2RGB(int val){ | |
float L = (Pixel.r_normalized(val) )*100; | |
float A = ((Pixel.g(val)-127)/254.0f)*200; | |
float B = ((Pixel.b(val)-127)/254.0f)*200; | |
// LAB to XYZ | |
float temp = (L+16)/116; | |
float x = LAB.Xn*LAB.funcInv(temp + (A/500)); | |
float y = LAB.Yn*LAB.funcInv(temp); | |
float z = LAB.Zn*LAB.funcInv(temp - (B/200)); | |
int r = Math.round(( 3.2404542f*x -1.5371385f*y -0.4985314f*z)*0xff ); | |
int g = Math.round((-0.9692660f*x +1.8760108f*y +0.0415560f*z)*0xff ); | |
int b = Math.round(( 0.0556434f*x -0.2040259f*y +1.0572252f*z)*0xff ); | |
int a = 255; | |
if(isOut(r)||isOut(g)||isOut(b)){ | |
a = 0; | |
} | |
return Pixel.argb_bounded(a, r, g, b); | |
} | |
static boolean isOut(int val){ | |
return (val&0xff) != val; | |
} | |
private static final class LAB { | |
static final float Xn = 0.95047f; | |
static final float Yn = 1.00000f; | |
static final float Zn = 1.08883f; | |
static final float lab6_29 = 6.0f/29.0f; | |
static final float lab6_29_3 = lab6_29*lab6_29*lab6_29; | |
static final float lab1_3_29_6_2 = (1.0f/3.0f) * (29.0f/6.0f) * (29.0f/6.0f); | |
static float func(float q){ | |
return q > lab6_29_3 ? (float)Math.cbrt(q):lab1_3_29_6_2*q + (4.0f/29.0f); | |
// return (float)Math.cbrt(q); | |
} | |
static float funcInv(float q){ | |
return q > lab6_29 ? q*q*q : 3*lab6_29*lab6_29*(q-(4.0f/29.0f)); | |
// return q*q*q; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment