diff --git a/spring-boot/src/main/java/org/springframework/boot/ImageBanner.java b/spring-boot/src/main/java/org/springframework/boot/ImageBanner.java index 41f8a1f245..ccd478404d 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ImageBanner.java +++ b/spring-boot/src/main/java/org/springframework/boot/ImageBanner.java @@ -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); + } + } }