RGB到飞利浦Hue(HSB)

我正在为Processing for a school for school做一个音乐播放器。 飞利浦Hue灯将产生一些相应的视觉效果。 我想让每首歌的视觉效果都是独一无二的。 因此,我获取了播放曲目的封面艺术(使用LastFM API)以获得最常用的颜色,并将其用作创建其他颜色的基础。 飞利浦Hue有一种不同的显示颜色的方式即(HSB)。 所以我通过转换它

Color.RGBtoHSB();

对于前者 它给出了R = 127,G = 190,B = 208,其值H = 0.5370371,S = 0.38942307,B = 0.8156863。 现在我猜测它们是在基数1上计算的,所以我将亮度和饱和度乘以255.而Hue乘以65535.(见http://developers.meethue.com/1_lightsapi.html )

在飞利浦Hue中设置这些计算值时,无论播放什么歌曲,颜色总是红色或白色。

RGB到HSB之间的转换出了什么问题?

在流行的请求我的代码:

作为测试:

 Color c = Colorconverter.getMostCommonColour("urltoimage"); float[] f = Colorconverter.getRGBtoHSB(c); ArrayList myLamps = PhilipsHue.getInstance().getMyLamps(); State state = new State(); state.setBri((int) Math.ceil(f[2]*255)); state.setSat((int) Math.ceil(f[1]*255)); state.setHue((int) Math.ceil(f[0]*65535)); state.setOn(true); PhilipsHue.setState(myLamps.get(1), state); 

function如上所示

  public static Color getMostCommonColour(String coverArtURL) { Color coulourHex = null; try { BufferedImage image = ImageIO.read(new URL(coverArtURL)); int height = image.getHeight(); int width = image.getWidth(); Map m = new HashMap(); for (int i = 0; i < width; i++) { for (int j = 0; j > 24) & 0xff; int red = (pixel >> 16) & 0xff; int green = (pixel >> 8) & 0xff; int blue = (pixel) & 0xff; return new int[] { red, green, blue }; } private static boolean isGray(int[] rgbArr) { int rgDiff = rgbArr[0] - rgbArr[1]; int rbDiff = rgbArr[0] - rgbArr[2]; // Filter out black, white and grays...... (tolerance within 10 pixels) int tolerance = 10; if (rgDiff > tolerance || rgDiff  tolerance || rbDiff < -tolerance) { return false; } return true; } public static float[] getRGBtoHSB(Color c) { float[] hsv = new float[3]; return Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), hsv); } 

设置状态只是简单地放到飞利浦灯泡上。 当我检查受影响灯泡上的JSON时

 { "state": { "on": true, "bri": 81, "hue": 34277, "sat": 18, "xy": [ 0.298, 0.2471 ], "ct": 153, "alert": "none", "effect": "none", "colormode": "hs", "reachable": true }, "type": "Extended color light", "name": "Hue Spot 1", "modelid": "LCT003", "swversion": "66010732", "pointsymbol": { "1": "none", "2": "none", "3": "none", "4": "none", "5": "none", "6": "none", "7": "none", "8": "none" } } 

特别感谢StackOverflow用户Gee858eeG注意我的错字和Erickson的优秀提示和链接。

这是一个将RGB颜色转换为Philips Hue XY值的工作函数。 返回的列表只包含两个元素0是X,1是Y.代码基于这个精彩的注释: https : //github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/commit/f41091cf671e13fe8c32fcced12604cd31cceaf3

事实上,这不会返回HSB值,XY值可以用来替换Hue上的颜色。希望它对其他人有用,因为飞利浦的API没有提到任何公式。

 public static List getRGBtoXY(Color c) { // For the hue bulb the corners of the triangle are: // -Red: 0.675, 0.322 // -Green: 0.4091, 0.518 // -Blue: 0.167, 0.04 double[] normalizedToOne = new double[3]; float cred, cgreen, cblue; cred = c.getRed(); cgreen = c.getGreen(); cblue = c.getBlue(); normalizedToOne[0] = (cred / 255); normalizedToOne[1] = (cgreen / 255); normalizedToOne[2] = (cblue / 255); float red, green, blue; // Make red more vivid if (normalizedToOne[0] > 0.04045) { red = (float) Math.pow( (normalizedToOne[0] + 0.055) / (1.0 + 0.055), 2.4); } else { red = (float) (normalizedToOne[0] / 12.92); } // Make green more vivid if (normalizedToOne[1] > 0.04045) { green = (float) Math.pow((normalizedToOne[1] + 0.055) / (1.0 + 0.055), 2.4); } else { green = (float) (normalizedToOne[1] / 12.92); } // Make blue more vivid if (normalizedToOne[2] > 0.04045) { blue = (float) Math.pow((normalizedToOne[2] + 0.055) / (1.0 + 0.055), 2.4); } else { blue = (float) (normalizedToOne[2] / 12.92); } float X = (float) (red * 0.649926 + green * 0.103455 + blue * 0.197109); float Y = (float) (red * 0.234327 + green * 0.743075 + blue * 0.022598); float Z = (float) (red * 0.0000000 + green * 0.053077 + blue * 1.035763); float x = X / (X + Y + Z); float y = Y / (X + Y + Z); double[] xy = new double[2]; xy[0] = x; xy[1] = y; List xyAsList = Doubles.asList(xy); return xyAsList; } 

我认为这里的问题是Hue的色域非常有限。 它对红色和紫色很重,但在蓝绿色区域不能产生那么多的饱和度。

我建议将饱和度设置为最大值255,并且仅改变色调。

根据文档中给出的表格,Hue的“hue”属性不会直接映射到HSV的色调。 近似可能足够接近,但如果没有,则尝试转换为CIE 1931颜色空间,然后设置“xy”属性而不是色调可能是值得的。

您的RGB作为HSB应分别为193度​​,39%和82%。 所以至少S和B似乎是正确的。 查看飞利浦hue API文档,您可以通过将这些数字乘以255来做正确的事情。

要将H值作为度数,请将计算出的H值乘以360.这就是您在案例中达到193的方式。 获得学位后,乘以182得到应发送给飞利浦hue API的值(来自Hack the Hue ):

 hue The parameters 'hue' and 'sat' are used to set the colour The 'hue' parameter has the range 0-65535 so represents approximately 182*degrees (technically 182.04 but the difference is imperceptible) 

这应该给你不同于你用* 65535方法获得的H值。