Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java RGB至飞利浦色调(HSB)_Java_Colors_Processing_Philips Hue - Fatal编程技术网

Java RGB至飞利浦色调(HSB)

Java RGB至飞利浦色调(HSB),java,colors,processing,philips-hue,Java,Colors,Processing,Philips Hue,我正在制作一个音乐播放器来处理学校的作业。飞利浦色调灯将产生一些相应的视觉效果。 我想让每首歌的视觉效果都与众不同。 因此,我获取了播放曲目的封面艺术(使用LastFM API)以获得最常用的颜色,并将其用作创建其他颜色的基础。 飞利浦色调有一种不同的显示颜色的方式,即HSB。所以我通过 Color.RGBtoHSB() 例如,它给出了R=127,G=190,B=208的值H=0.5370371,S=0.38942307,B=0.8156863。现在我猜它们是在1的基础上计算的,所以我把亮度乘以

我正在制作一个音乐播放器来处理学校的作业。飞利浦色调灯将产生一些相应的视觉效果。 我想让每首歌的视觉效果都与众不同。 因此,我获取了播放曲目的封面艺术(使用LastFM API)以获得最常用的颜色,并将其用作创建其他颜色的基础。 飞利浦色调有一种不同的显示颜色的方式,即HSB。所以我通过

Color.RGBtoHSB()

例如,它给出了R=127,G=190,B=208的值H=0.5370371,S=0.38942307,B=0.8156863。现在我猜它们是在1的基础上计算的,所以我把亮度乘以255。色调是65535。 (如图所示)

在飞利浦色调中设置这些计算值时,无论播放什么歌曲,颜色始终为redish或白色

RGB到HSB之间的转换是否出现问题

应大众要求,我的代码:

作为测试:

Color c = Colorconverter.getMostCommonColour("urltoimage");
float[] f = Colorconverter.getRGBtoHSB(c);
ArrayList<Lamp> 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);

作为HSB,您的RGB应分别为193度、39%和82%。所以至少S和B看起来是正确的。查看Philips hue API文档,将这些数字乘以255是正确的

要以度的形式获得H值,请将计算出的H值乘以360。这就是你如何到达193的原因。获得学位后,乘以182得到应发送至飞利浦色调API的值(从):


与使用
*65535
方法获得的H值相比,这会给您带来不同的H值。

我认为这里的问题是,它含有大量的红色和紫色,但不能在蓝绿色区域产生足够的饱和度

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


根据文档中给出的表格,色调的“色调”属性不会直接映射到HSV的色调。近似值可能足够接近,但如果不接近,则可能值得尝试一次,然后设置“xy”属性而不是色调。

特别感谢StackOverflow用户Gee858eeG注意到我的打字错误和Erickson提供的大量提示和链接

这是一个工作函数,用于将任何RGB颜色转换为Philips色调XY值。返回的列表只包含两个元素,0是X,1是Y。 代码基于以下精彩注释:

尽管这不会返回HSB值,但XY值可以用来替代色调上的颜色变化。希望它能对其他人有所帮助,因为飞利浦的API没有提到任何公式

public static List<Double> 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<Double> xyAsList = Doubles.asList(xy);
    return xyAsList;
}
公共静态列表getRGBtoXY(c色){
//对于色调灯泡,三角形的角是:
//-红色:0.675,0.322
//-绿色:0.4091,0.518
//-蓝色:0.167,0.04
double[]normalizedToOne=新的double[3];
浮动信用、绿色、蓝色;
cred=c.getRed();
cgreen=c.getGreen();
cblue=c.getBlue();
标准化TONE[0]=(cred/255);
normalizedToOne[1]=(cgreen/255);
标准化TONE[2]=(cblue/255);
漂浮着红、绿、蓝;
//使红色更生动
如果(标准化TONE[0]>0.04045){
红色=(浮点)Math.pow(
(标准化TONE[0]+0.055)/(1.0+0.055),2.4);
}否则{
红色=(浮动)(标准化TONE[0]/12.92);
}
//使绿色更生动
如果(标准化TONE[1]>0.04045){
绿色=(浮点)数学功率((标准化TONE[1]+0.055)
/ (1.0 + 0.055), 2.4);
}否则{
绿色=(浮动)(标准化TONE[1]/12.92);
}
//使蓝色更生动
如果(标准化TONE[2]>0.04045){
蓝色=(浮点)数学功率((标准化TONE[2]+0.055)
/ (1.0 + 0.055), 2.4);
}否则{
蓝色=(浮动)(标准化TONE[2]/12.92);
}
浮动X=(浮动)(红色*0.649926+绿色*0.103455+蓝色*0.197109);
浮动Y=(浮动)(红色*0.234327+绿色*0.743075+蓝色*0.022598);
浮动Z=(浮动)(红色*0.0000000+绿色*0.053077+蓝色*1.035763);
浮动x=x/(x+Y+Z);
浮动y=y/(X+y+Z);
double[]xy=新的double[2];
xy[0]=x;
xy[1]=y;
List xyAsList=双倍。asList(xy);
返回xyAsList;
}

HSB值看起来正确。我去了colorpicker.com。它接受的H、S、B的最大值为360、100、100(如Gary所说),因此您的值转换为H=193、S=39、B=82,显示为蓝色,RGB非常接近您的原始值。我会仔细检查硬件文档,找出它期望的值(最重要的是,值的范围)。@GaryKlasen否,使用0-255的值表示亮度和饱和度,0-65535的值表示色调角度。而不是使用从RGB计算的值来测试灯光,尝试对已知颜色的HSB值进行硬编码,并确保灯光正常工作。换言之,通过确定转换是否错误,或者与灯的通信是否中断来隔离问题。我不是说灯泡坏了,而是质疑错误是否在转换中或稍后的代码。划分搜索空间的简单测试是基本的调试策略。发布一篇文章,因为对代码的描述和结果不匹配。确实离题了,但还是忍不住:编写一个灯泡需要多少程序员Pd不同,但仅取决于您引入的舍入误差。RGB到HSB转换返回的色调值是0–1之间的浮点值。0.5370371*65535=35195,接近通过四舍五入色调角度(193.33)和转换因子(182.04)得到的35126值。谢谢!但飞利浦的灯泡仍然显示出白色,而不是colorpicker.com上显示的蓝色。飞利浦API表示色调值是介于0和65535之间的包装值。0和65535都是红色,25500是绿色,46920是蓝色。我的值应该接近46920。如果我做你的计算。0.5370371*360°=193.333356 mul
{
    "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"
    }
}
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)
public static List<Double> 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<Double> xyAsList = Doubles.asList(xy);
    return xyAsList;
}