mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
try gradients in Lab space, add pref to use them
This commit is contained in:
@@ -202,6 +202,15 @@ public class Theme {
|
||||
|
||||
|
||||
static public Image makeGradient(String attribute, int wide, int high) {
|
||||
if ("lab".equals(Preferences.get("theme.gradient.method"))) {
|
||||
return makeGradientLab(attribute, wide, high);
|
||||
} else { // otherwise go with the default
|
||||
return makeGradientRGB(attribute, wide, high);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static private Image makeGradientRGB(String attribute, int wide, int high) {
|
||||
int top = getColor(attribute + ".gradient.top").getRGB();
|
||||
int bot = getColor(attribute + ".gradient.bottom").getRGB();
|
||||
|
||||
@@ -216,4 +225,156 @@ public class Theme {
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
|
||||
static private Image makeGradientLab(String attribute, int wide, int high) {
|
||||
double[] top = xyzToLab(rgbToXyz(getColor(attribute + ".gradient.top")));
|
||||
double[] bot = xyzToLab(rgbToXyz(getColor(attribute + ".gradient.bottom")));
|
||||
|
||||
double diffL = bot[0] - top[0];
|
||||
double diffA = bot[1] - top[1];
|
||||
double diffB = bot[2] - top[2];
|
||||
|
||||
BufferedImage outgoing =
|
||||
new BufferedImage(wide, high, BufferedImage.TYPE_INT_RGB);
|
||||
int[] row = new int[wide];
|
||||
WritableRaster wr = outgoing.getRaster();
|
||||
for (int i = 0; i < high; i++) {
|
||||
double amt = i / (high - 1.0);
|
||||
double el = top[0] + amt * diffL;
|
||||
double ay = top[1] + amt * diffA;
|
||||
double be = top[2] + amt * diffB;
|
||||
int rgb = argb(xzyToRgb(labToXyz(el, ay, be)));
|
||||
Arrays.fill(row, rgb);
|
||||
wr.setDataElements(0, i, wide, 1, row);
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
|
||||
// https://web.archive.org/web/20060213080500/http://www.easyrgb.com/math.php?MATH=M2#text2
|
||||
|
||||
// Observer= 2°, Illuminant= D65;
|
||||
static final double REF_X = 95.047;
|
||||
static final double REF_Y = 100.0;
|
||||
static final double REF_Z = 108.883;
|
||||
|
||||
|
||||
static private double[] rgbToXyz(Color color) {
|
||||
double var_R = color.getRed() / 255.0;
|
||||
double var_G = color.getGreen() / 255.0;
|
||||
double var_B = color.getBlue() / 255.0;
|
||||
|
||||
var_R = 100 * ((var_R > 0.04045) ?
|
||||
Math.pow((var_R + 0.055) / 1.055, 2.4) : var_R / 12.92);
|
||||
var_G = 100 * ((var_G > 0.04045) ?
|
||||
Math.pow((var_G + 0.055) / 1.055, 2.4) : var_G / 12.92);
|
||||
var_B = 100 * ((var_B > 0.04045) ?
|
||||
Math.pow((var_B + 0.055) / 1.055, 2.4) : var_B / 12.92);
|
||||
|
||||
// Observer = 2°, Illuminant = D65
|
||||
return new double[] {
|
||||
var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805,
|
||||
var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722,
|
||||
var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static private double[] xyzToLab(double[] xyz) {
|
||||
double var_X = xyz[0] / REF_X; // Observer= 2°, Illuminant= D65
|
||||
double var_Y = xyz[1] / REF_Y;
|
||||
double var_Z = xyz[2] / REF_Z;
|
||||
|
||||
var_X = (var_X > 0.008856) ?
|
||||
Math.pow(var_X, 1/3.0) : (7.787*var_X + 16/116.0);
|
||||
|
||||
var_Y = (var_Y > 0.008856) ?
|
||||
Math.pow(var_Y, 1/3.0) : (7.787*var_Y + 16/116.0);
|
||||
|
||||
var_Z = (var_Z > 0.008856) ?
|
||||
Math.pow(var_Z, 1/3.0) : (7.787*var_Z + 16/116.0);
|
||||
|
||||
return new double[] {
|
||||
(116 * var_Y) - 16,
|
||||
500 * (var_X - var_Y),
|
||||
200 * (var_Y - var_Z)
|
||||
};
|
||||
}
|
||||
|
||||
// static private double[] labToXyz(double[] lab) {
|
||||
// double var_Y = (lab[0] + 16) / 116.0;
|
||||
// double var_X = lab[1] / 500 + var_Y;
|
||||
// double var_Z = var_Y - lab[2] / 200.0;
|
||||
static private double[] labToXyz(double el, double ay, double be) {
|
||||
double var_Y = (el + 16) / 116;
|
||||
double var_X = ay / 500 + var_Y;
|
||||
double var_Z = var_Y - be / 200;
|
||||
|
||||
// if ( var_Y^3 > 0.008856 ) var_Y = var_Y^3
|
||||
// else var_Y = ( var_Y - 16 / 116 ) / 7.787
|
||||
// if ( var_X^3 > 0.008856 ) var_X = var_X^3
|
||||
// else var_X = ( var_X - 16 / 116 ) / 7.787
|
||||
// if ( var_Z^3 > 0.008856 ) var_Z = var_Z^3
|
||||
// else var_Z = ( var_Z - 16 / 116 ) / 7.787
|
||||
|
||||
final double amt = Math.pow(0.008856, 1/3.0);
|
||||
var_Y = (var_Y > amt) ?
|
||||
Math.pow(var_Y, 3) : (var_Y - 16/116.0) / 7.787;
|
||||
var_X = (var_X > amt) ?
|
||||
Math.pow(var_X, 3) : (var_X - 16/116.0) / 7.787;
|
||||
var_Z = (var_Z > amt) ?
|
||||
Math.pow(var_Z, 3) : (var_Z - 16/116.0) / 7.787;
|
||||
|
||||
// X = ref_X * var_X //ref_X = 95.047 Observer= 2°, Illuminant= D65
|
||||
// Y = ref_Y * var_Y //ref_Y = 100.000
|
||||
// Z = ref_Z * var_Z //ref_Z = 108.883
|
||||
return new double[] {
|
||||
REF_X * var_X,
|
||||
REF_Y * var_Y,
|
||||
REF_Z * var_Z
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static private double[] xzyToRgb(double[] xyz) {
|
||||
double var_X = xyz[0] / 100; // Where X = 0 ÷ 95.047
|
||||
double var_Y = xyz[1] / 100; // Where Y = 0 ÷ 100.000
|
||||
double var_Z = xyz[2] / 100; // Where Z = 0 ÷ 108.883
|
||||
|
||||
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
|
||||
double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
|
||||
double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
|
||||
|
||||
// if ( var_R > 0.0031308 ) var_R = 1.055 * ( var_R ^ ( 1 / 2.4 ) ) - 0.055
|
||||
// else var_R = 12.92 * var_R
|
||||
// if ( var_G > 0.0031308 ) var_G = 1.055 * ( var_G ^ ( 1 / 2.4 ) ) - 0.055
|
||||
// else var_G = 12.92 * var_G
|
||||
// if ( var_B > 0.0031308 ) var_B = 1.055 * ( var_B ^ ( 1 / 2.4 ) ) - 0.055
|
||||
// else var_B = 12.92 * var_B
|
||||
|
||||
var_R = (var_R > 0.0031308) ?
|
||||
1.055 * Math.pow(var_R, 1/2.4) - 0.055 : 12.92 * var_R;
|
||||
var_G = (var_G > 0.0031308) ?
|
||||
1.055 * Math.pow(var_G, 1/2.4) - 0.055 : 12.92 * var_G;
|
||||
var_B = (var_B > 0.0031308) ?
|
||||
1.055 * Math.pow(var_B, 1/2.4) - 0.055 : 12.92 * var_B;
|
||||
|
||||
return new double[] {
|
||||
var_R * 255,
|
||||
var_G * 255,
|
||||
var_B * 255
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static private int bounded(double amount) {
|
||||
return Math.max(0, Math.min((int) Math.round(amount), 255));
|
||||
}
|
||||
|
||||
|
||||
static private int argb(double[] rgb) {
|
||||
return 0xff000000 |
|
||||
bounded(rgb[0]) << 16 | bounded(rgb[1]) << 8 | bounded(rgb[2]);
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,9 @@ chooser.files.native = true
|
||||
# https://github.com/processing/processing4/issues/77
|
||||
#chooser.files.native.macos = false
|
||||
|
||||
# set to 'lab' to interpolate theme gradients using L*a*b* color space
|
||||
theme.gradient.method = rgb
|
||||
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
@@ -93,6 +96,7 @@ update.check = true
|
||||
# on windows, automatically associate .pde files with processing.exe
|
||||
platform.auto_file_type_associations = true
|
||||
|
||||
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
# default font used for UI elements (no longer in use as of beta 9)
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
1285 (4.0?)
|
||||
X try gradients in Lab space
|
||||
X not an obvious win, so set as a pref and come back to it later
|
||||
|
||||
docs
|
||||
X update theme instructions
|
||||
X https://github.com/processing/processing4/wiki/Themes
|
||||
X update the platforms page
|
||||
X https://github.com/processing/processing4/wiki/Supported-Platforms
|
||||
o rename to 'platforms'?
|
||||
|
||||
cleaning
|
||||
X the gradient.top and gradient.bottom lines are used by makeGradient(),
|
||||
X so search for makeGradient() calls to see whether they're still in use.
|
||||
X having brought back some gradient themes for beta 9, we'll keep this in place
|
||||
|
||||
|
||||
known issues
|
||||
@@ -169,17 +181,13 @@ _ theme_selector.combo_box.enabled.bgcolor
|
||||
_ theme_selector.combo_box.enabled.bgcolor
|
||||
_ don’t update dynamically unless you (a) select ‘Minerals’ or ‘Alloys’
|
||||
_ or (b) open, then close the dropdown
|
||||
_ build new welcome/examples screen for startup
|
||||
_ implement document icons on Windows
|
||||
_ implement document icons on Linux
|
||||
_ add notes about params to the wiki
|
||||
_ the gradient.top and gradient.bottom lines are used by makeGradient(),
|
||||
_ so search for makeGradient() calls to see whether they're still in use.
|
||||
|
||||
|
||||
4.0
|
||||
_ how to handle contrib manager download/retry/etc and showing progress
|
||||
_ do gradients in Lab space
|
||||
_ adding a file to an untitled sketch should require a save
|
||||
_ Cannot type quotes with an international keyboard on MacOS
|
||||
_ fixed by turning on "Enable complex text input"
|
||||
@@ -195,19 +203,22 @@ _ really a drag for version control
|
||||
_ https://github.com/processing/processing/issues/5848
|
||||
_ or at least avoid the multiple
|
||||
_ https://github.com/processing/processing4/issues/330
|
||||
_ update the platforms page
|
||||
_ https://github.com/processing/processing4/wiki/Supported-Platforms
|
||||
_ if error in the code during export, it's just saying "error during export"
|
||||
_ is this still the case?
|
||||
_ chars[] array is never used in ascii video example
|
||||
_ ui scaling in the PDE is important for classes/seeing at a distance
|
||||
_ Export to Application was broken with OpenGL (Casey)
|
||||
_ add a version of this to the 4.x repo
|
||||
_ https://github.com/processing/processing/wiki/troubleshooting
|
||||
_ and update the Help menu to link to it
|
||||
_ and maybe the FAQ too?
|
||||
|
||||
|
||||
4.0 / with Casey
|
||||
_ Export to Application was broken with OpenGL (Casey)
|
||||
_ resolution for the About screen
|
||||
_ examples still coming from processing-docs repo
|
||||
_ chars[] array is never used in ascii video example
|
||||
|
||||
|
||||
4.0 / movie maker
|
||||
_ break Movie Maker out to its own library?
|
||||
_ another big leap in file size reduction for the PDE download
|
||||
|
||||
Reference in New Issue
Block a user