首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将RGB转换为HSB (又名HSV)

将RGB转换为HSB (又名HSV)
EN

Stack Overflow用户
提问于 2015-01-13 14:32:06
回答 1查看 251关注 0票数 0

我正在尝试实现一个简单的RGB到HSB例程,我已经严格遵循了维基百科参考文章的指示。

我所写的代码是:

代码语言:javascript
复制
#include <iostream>
#include <cmath>

struct RGB { float red, green, blue; };
struct HSB { float hue, saturation, brightness; }; // aka HSV

// https://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
static void HSBToRGB(HSB const & hsb, RGB & rgb )
{
  /*
   * Given a color with hue H ∈ [0°, 360°), saturation SHSV ∈ [0, 1], and value
   * V ∈ [0, 1], we first find chroma:
   */
  const float H = hsb.hue;
  const float S_HSV = hsb.saturation;
  const float V = hsb.brightness;
  const float C = V * S_HSV;
  /*
  * Then we can find a point (R1, G1, B1) along the bottom three faces of the RGB
  * cube, with the same hue and chroma as our color (using the intermediate value X
  * for the second largest component of this color):
  */
  const float H_prime = H / 60.;
  const float X = C * ( 1 - std::abs( (int)H_prime % 2 - 1) );
  float R1, G1, B1;
  if( isnan( H ) )
    {
    R1 = G1 = B1 = 0;
    }
  else if( 0 <= H_prime && H_prime < 1 )
    {
    R1 = C; G1 = X; B1 = 0;
    }
  else if( 1 <= H_prime && H_prime < 2 )
    {
    R1 = X; G1 = C; B1 = 0;
    }
  else if( 2 <= H_prime && H_prime < 3 )
    {
    R1 = 0; G1 = C; B1 = X;
    }
  else if( 3 <= H_prime && H_prime < 4 )
    {
    R1 = 0; G1 = X; B1 = C;
    }
  else if( 4 <= H_prime && H_prime < 5 )
    {
    R1 = X; G1 = 0; B1 = C;
    }
  else if( 5 <= H_prime && H_prime < 6 )
    {
    R1 = C; G1 = 0; B1 = X;
    }

  /*
   * Finally, we can find R, G, and B by adding the same amount to each component,
   * to match value:
   */
  const float m = V - C;
  rgb.red   = R1 + m;
  rgb.green = G1 + m;
  rgb.blue  = B1 + m;
}

int main()
{
  HSB const hsb = { 251.1f, 0.887f, 0.918f };
  RGB rgb = { 0.255f , 0.104f , 0.918f };
  std::cout << "Reference: " << rgb.red << "," << rgb.green << "," << rgb.blue << std::endl;
  HSBToRGB(hsb, rgb);
  std::cout << "Computed:  " << rgb.red << "," << rgb.green << "," << rgb.blue << std::endl;

  return 0;
}

在linux /jessie amd64上编译和运行时,我得到的是:

代码语言:javascript
复制
$ ./ref
Reference: 0.255,0.104,0.918
Computed:  0.103734,0.103734,0.918

现在,如果您查找正确的引用值(同一条,表中的第11行),它应该是相同的。我不明白的是,Hue的差值很大(0.255 != 0.103734)。

我一直在重复检查我的实现与维基百科文章描述的内容,并且找不到任何不同之处。

使用java作为参考,我可以检查RGB值是否正确,例如:

代码语言:javascript
复制
import java.awt.Color;

public class HSBToRGBExample {
  public static void main(String[] args) {
    float hue = 251.1f / 360;
    float saturation = 0.887f;
    float brightness = 0.918f;
    int rgb = Color.HSBtoRGB(hue, saturation, brightness);
    int red = (rgb >> 16) & 0xFF;
    int green = (rgb >> 8) & 0xFF;
    int blue = rgb & 0xFF;
    System.out.println((float)red / 255 + " " + (float)green / 255 + " " + (float)blue / 255);
  }
}

维基百科的文章中有错误吗?或者在我的实现中缺少什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-13 15:04:43

您需要浮点模数,但您正在转换到一个int (可能是为了平息编译器关于%只适用于整数的抱怨)。

在C++中

代码语言:javascript
复制
std::abs(std::fmod(H_prime, 2) - 1);

(由于浮点不精确,您仍然会看到差异。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27924494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档