如何将java.awt.Color转为HSL并微调亮度(增减L值)?
实现java.awt.Color的HSL亮度微调
当然可以实现基于HSL亮度(L值)的颜色明暗调整。你遇到的HSB和HSL亮度效果差异,是因为两者的亮度计算逻辑完全不同:HSB的B是明度(Brightness),代表颜色的整体明亮程度;而HSL的L是亮度(Lightness),基于RGB的最大最小值的平均值计算,调整时的视觉效果更符合人眼感知。
下面提供两种简洁实现方案:
方案一:手动实现RGB↔HSL转换
自己编写核心转换逻辑,不依赖第三方库,代码可控性强:
import java.awt.Color; public class HslColorUtils { // 增加L值(变亮),delta范围建议-100到100 public static Color lighten(Color color, int delta) { return adjustLightness(color, delta); } // 减少L值(变暗) public static Color darken(Color color, int delta) { return adjustLightness(color, -delta); } private static Color adjustLightness(Color color, int delta) { // RGB转HSL float r = color.getRed() / 255.0f; float g = color.getGreen() / 255.0f; float b = color.getBlue() / 255.0f; float max = Math.max(r, Math.max(g, b)); float min = Math.min(r, Math.min(g, b)); float h, s, l = (max + min) / 2; if (max == min) { h = s = 0; // 灰度 } else { float d = max - min; s = l > 0.5f ? d / (2 - max - min) : d / (max + min); if (max == r) h = (g - b) / d + (g < b ? 6 : 0); else if (max == g) h = (b - r) / d + 2; else h = (r - g) / d + 4; h /= 6; } // 调整L值,限制在0-100范围(转成0-1的浮点) l = Math.min(Math.max(l + delta / 100.0f, 0.0f), 1.0f); // HSL转RGB float m1, m2; m2 = l <= 0.5f ? l * (1 + s) : l + s - l * s; m1 = 2 * l - m2; return new Color( clamp(hueToRgb(m1, m2, h + 1/3f)), clamp(hueToRgb(m1, m2, h)), clamp(hueToRgb(m1, m2, h - 1/3f)) ); } private static float hueToRgb(float m1, float m2, float h) { h = (h < 0) ? h + 1 : (h > 1) ? h - 1 : h; if (6 * h < 1) return m1 + (m2 - m1) * 6 * h; if (2 * h < 1) return m2; if (3 * h < 2) return m1 + (m2 - m1) * (2/3f - h) * 6; return m1; } private static int clamp(float value) { int intVal = Math.round(value * 255); return Math.min(Math.max(intVal, 0), 255); } public static void main(String[] args) { Color original = new Color(184, 207, 229); Color lighter = lighten(original, 10); // 亮度+10 Color darker = darken(original, 10); // 亮度-10 System.out.println("原始颜色: " + original); System.out.println("变亮10单位: " + lighter); System.out.println("变暗10单位: " + darker); } }
方案二:使用Apache Commons Imaging库
如果不想自己写转换逻辑,Apache Commons Imaging(原Sanselan)提供了现成的HSL颜色处理工具,代码更简洁:
- 先引入Maven依赖:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-imaging</artifactId> <version>1.0-alpha3</version> </dependency>
- 实现代码:
import java.awt.Color; import org.apache.commons.imaging.color.ColorHsl; import org.apache.commons.imaging.color.ColorRgb; public class HslColorUtils { public static Color lighten(Color color, int delta) { ColorRgb rgb = new ColorRgb(color.getRed(), color.getGreen(), color.getBlue()); ColorHsl hsl = ColorHsl.fromColorRgb(rgb); // 调整L值,限制在0-100 float newL = Math.min(Math.max(hsl.L + delta, 0f), 100f); ColorRgb newRgb = hsl.toColorRgb(new ColorHsl(hsl.H, hsl.S, newL)); return new Color(newRgb.getRed(), newRgb.getGreen(), newRgb.getBlue()); } public static Color darken(Color color, int delta) { return lighten(color, -delta); } public static void main(String[] args) { Color original = new Color(184, 207, 229); System.out.println("原始颜色: " + original); System.out.println("变亮10单位: " + lighten(original, 10)); System.out.println("变暗10单位: " + darken(original, 10)); } }
两种方案都能精准基于HSL的L值调整亮度,解决你之前用HSB带来的效果差异问题。
内容的提问来源于stack exchange,提问作者Heneh
相关产品推荐
相关产品推荐

