Add ImageBanner color distance calculation
Support CIE94 color distance calculations for improved ImageBanner rendering. Based on code originally developed by Michael Simons and added with his permission. See gh-4647
This commit is contained in:
parent
58d77ec961
commit
60500aef9b
|
|
@ -18,6 +18,7 @@ package org.springframework.boot;
|
|||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
import java.awt.color.ColorSpace;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
|
|
@ -214,15 +215,6 @@ public class ImageBanner implements Banner {
|
|||
}
|
||||
}
|
||||
|
||||
private static double getColorDistance(Color color1, Color color2) {
|
||||
double redDelta = (color1.getRed() - color2.getRed()) * RED_WEIGHT;
|
||||
double greenDelta = (color1.getGreen() - color2.getGreen()) * GREEN_WEIGHT;
|
||||
double blueDelta = (color1.getBlue() - color2.getBlue()) * BLUE_WEIGHT;
|
||||
|
||||
return Math.pow(redDelta, 2.0d) + Math.pow(greenDelta, 2.0d)
|
||||
+ Math.pow(blueDelta, 2.0d);
|
||||
}
|
||||
|
||||
private static BufferedImage resizeImage(BufferedImage sourceImage, int maxWidth,
|
||||
double aspectRatio) {
|
||||
int width;
|
||||
|
|
@ -246,4 +238,79 @@ public class ImageBanner implements Banner {
|
|||
resizedImage.getGraphics().drawImage(image, 0, 0, null);
|
||||
return resizedImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the CIE94 distance between two colors.
|
||||
*
|
||||
* Contributed by michael-simons
|
||||
* (original implementation https://github.com/michael-simons/dfx-mosaic/blob/public/src/main/java/de/dailyfratze/mosaic/images/CIE94ColorDistance.java)
|
||||
*
|
||||
* @param color1 the first color
|
||||
* @param color2 the second color
|
||||
* @return the distance between the colors
|
||||
*/
|
||||
private static double getColorDistance(final Color color1, final Color color2) {
|
||||
// Convert to L*a*b* color space
|
||||
float[] lab1 = toLab(color1);
|
||||
float[] lab2 = toLab(color2);
|
||||
|
||||
// Make it more readable
|
||||
double L1 = lab1[0];
|
||||
double a1 = lab1[1];
|
||||
double b1 = lab1[2];
|
||||
double L2 = lab2[0];
|
||||
double a2 = lab2[1];
|
||||
double b2 = lab2[2];
|
||||
|
||||
// CIE94 coefficients for graphic arts
|
||||
double kL = 1;
|
||||
double K1 = 0.045;
|
||||
double K2 = 0.015;
|
||||
// Weighting factors
|
||||
double sl = 1.0;
|
||||
double kc = 1.0;
|
||||
double kh = 1.0;
|
||||
|
||||
// See http://en.wikipedia.org/wiki/Color_difference#CIE94
|
||||
double c1 = Math.sqrt(a1 * a1 + b1 * b1);
|
||||
double deltaC = c1 - Math.sqrt(a2 * a2 + b2 * b2);
|
||||
double deltaA = a1 - a2;
|
||||
double deltaB = b1 - b2;
|
||||
double deltaH = Math.sqrt(Math.max(0.0, deltaA * deltaA + deltaB * deltaB - deltaC * deltaC));
|
||||
|
||||
return Math.sqrt(Math.max(0.0, Math.pow((L1 - L2) / (kL * sl), 2) + Math.pow(deltaC / (kc * (1 + K1 * c1)), 2) + Math.pow(deltaH / (kh * (1 + K2 * c1)), 2.0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CIE L*a*b* values of this color.
|
||||
*
|
||||
* Implements the forward transformation described in
|
||||
* https://en.wikipedia.org/wiki/Lab_color_space
|
||||
*
|
||||
* @param color the color to convert
|
||||
* @return the xyz color components
|
||||
*/
|
||||
static float[] toLab(Color color) {
|
||||
float[] xyz = color.getColorComponents(
|
||||
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ), null);
|
||||
|
||||
return xyzToLab(xyz);
|
||||
}
|
||||
|
||||
static float[] xyzToLab(float[] colorvalue) {
|
||||
double l = f(colorvalue[1]);
|
||||
double L = 116.0 * l - 16.0;
|
||||
double a = 500.0 * (f(colorvalue[0]) - l);
|
||||
double b = 200.0 * (l - f(colorvalue[2]));
|
||||
return new float[]{(float) L, (float) a, (float) b};
|
||||
}
|
||||
|
||||
private static double f(double t) {
|
||||
if (t > 216.0 / 24389.0) {
|
||||
return Math.cbrt(t);
|
||||
}
|
||||
else {
|
||||
return (1.0 / 3.0) * Math.pow(29.0 / 6.0, 2) * t + (4.0 / 29.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue