在 C++ 中可视化从红色到蓝色的 RGB 渐变
Visualize RGB gradient going from red to blue in C++
我有一个介于 0 和 1 之间的值,我试图确定一个颜色值来表示该值的大小。数值越高越"blue",数值越低越红,中间是绿色。所以RGB中的float值1应该是(0,0,255),RGB中的值0应该是(255,0,0),中间是(0,255,0)。我试图实现它,但在我的实现中,最高值是白色,最低值是黑色,这不是我想要实现的。
有人知道如何实现吗?
我的尝试是:
unsigned int rgb[] = {0,0,0};
//16581375 = 255^3
unsigned long colorValue = floatBetweenZeroAndOne * 16581375;
rgb[0] = colorValue %255;
rgb[1] = (colorValue / 255) % 255;
rgb[2] = ((colorValue / 255) / 255) % 255;
试试这个:
unsigned int rgb[] = { 0,0,0 };
float floatBetweenZeroAndOne = 0.25f;
if (floatBetweenZeroAndOne <= 0.5f)
{
floatBetweenZeroAndOne *= 2.0f;
rgb[0] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
rgb[1] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
}
else
{
floatBetweenZeroAndOne = floatBetweenZeroAndOne * 2.0f - 1.0f;
rgb[1] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
rgb[2] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
}
它将平滑地在 R G B 分量之间插入 float
颜色值。
所以基本上你是说 rgb[0] 如果你的 float 变量是 0 应该是 0 如果你的变量是 1 它应该是 255。你的 float 变量 * 255 应该可以解决红色问题。从现在开始,让我们将您的浮点变量称为 floatValue。
现在让我们来做蓝色。这基本上与红色相反。我们希望当 floatValue 为 0 时蓝色为 255,当 floatValue 为 1 时蓝色为 0。您可以这样使用它:rgb[2] = 255 - floatValue * 255.
我猜绿色的是最棘手的。我们希望该值在 0 < floatValue < 0.5 时上升并在 0.5 < floatValue < 1 时下降。我认为 if 语句可以解决问题。
总的来说,我会这样编码。我没有测试过。
unsigned float floatValue = 0.236; // Completely random number between zero and one.
unsigned int rgb[] = {0,0,0};
rgb[0] = floatValue * 255;
rgb[2] = 255 - floatValue * 255;
if (floatValue > 0 && <= 0.5)
{
rgb[1] = floatValue * 512 // Since I guess you want it to be maxed out at 128.
}
else if (floatValue > 0.5 && floatValue <= 1)
{
rgb[1] = 255 - (floatValue - 0.5)*512;
}
else
{
cout << "floatValue has a value smaller than 0 or bigger than 1!";
return -1;
}
像这样的函数应该可以完成工作
void setColor(double value, int* rgb){
if(value > 1 || value < 0) return;
if(value > 0.5){
value -= 0.5;
rgb[0] = 0;
rgb[1] = (int)((1-2*value)*255);
rgb[2] = (int)(2*value*255);
}
if(value <= 0.5){
rgb[0] = (int)((1-2*value)*255);
rgb[1] = (int)(2*value*255);
rgb[2] = 0;
}
}
你也可以试试这个版本:
void rgbscalar(float scalar)
{
float ratio = 2 * scalar;
int r = 255 * (ratio - 1);
if ( r < 0 ) r = 0;
int b = 255 * (1 - ratio);
if ( b < 0 ) b = 0;
int g = 255 - b - r;
if ( g < 0 ) g = 0;
std::cout << r << " " << g << " " << b << " : " << scalar << std::endl;
}
此代码是从颜色 1 到颜色 2 的通用线性渐变;您可以使用它来制作多个渐变,例如,红色到绿色和绿色到蓝色,并使用 c1 和 c2 之间的变化填充数组。
如果有人知道编写此代码的更好方法,请随时提出建议:)。
#include <cstdint> # Defines uint_fast32_t
#pragma GCC diagnostic push // GCC only
#pragma GCC diagnostic ignored "-Wconversion" // GCC only, disable bitfield warnings
//+------------------------------------------------------------------+
// Color
// Parameters c1 and c2 are ARGB Colors to Gradient into the return value
// Gradient and Alpha is a percentage from c1 towards c2, accepts any range, but anything out of [0; 1.0] is cut
// The return value of the function is guaranteed to be between [0xYY000000; 0xYYFFFFFF], even if the gradient is invalid, and YY equals to the Alpha between [0; 1.0] -> AA[0; 255] proportionally
//+------------------------------------------------------------------+
uint_fast32_t argbGradient(uint_fast32_t c1, uint_fast32_t c2, double gradient = 0.5, double alpha = 0.0)
{
uint_fast32_t c = 0x00000000;
// Red is at 0x000000##
// Green is at 0x0000##00
// Blue is at 0x00##0000
// Alpha is at 0x##000000
if(gradient > 1.0) gradient = 1.0;
else if (gradient < +0.0) gradient = +0.0;
if(alpha > 1.0) alpha = 1.0;
else if(alpha < +0.0) alpha = +0.0;
uint_fast32_t red1 = (c1 & 0xFF);
uint_fast32_t green1 = (c1 & 0xFF00) >> 8;
uint_fast32_t blue1 = (c1 & 0xFF0000) >> 16;
uint_fast32_t alpha1 = (c1 & 0xFF000000) >> 24;
uint_fast32_t red2 = (c2 & 0xFF);
uint_fast32_t green2 = (c2 & 0xFF00) >> 8;
uint_fast32_t blue2 = (c2 & 0xFF0000) >> 16;
uint_fast32_t alpha2 = (c2 & 0xFF000000) >> 24;
if (red1 > red2) c = ((uint_fast32_t) (red1 - ((double) (red1 - red2) * gradient))) & 0xFF;
else c = ((uint_fast32_t) (red1 + ((double) (red2 - red1) * gradient))) & 0xFF;
if (green1 > green2) c = ((((uint_fast32_t) (green1 - ((double) (green1 - green2) * gradient))) & 0xFF) << 8) + c;
else c = ((((uint_fast32_t) (green1 + ((double) (green2 - green1) * gradient))) & 0xFF) << 8) + c;
if (blue1 > blue2) c = ((((uint_fast32_t) (blue1 - ((double) (blue1 - blue2) * gradient))) & 0xFF) << 16) + c;
else c = ((((uint_fast32_t) (blue1 + ((double) (blue2 - blue1) * gradient))) & 0xFF) << 16) + c;
if (alpha1 > alpha2) c = ((((uint_fast32_t) (alpha1 - ((double) (alpha1 - alpha2) * alpha))) & 0xFF) << 24) + c;
else c = ((((uint_fast32_t) (alpha1 + ((double) (alpha2 - alpha1) * alpha))) & 0xFF) << 24) + c;
return c;
}
#pragma GCC diagnostic pop // GCC only, restore specifically disabled flags
我有一个介于 0 和 1 之间的值,我试图确定一个颜色值来表示该值的大小。数值越高越"blue",数值越低越红,中间是绿色。所以RGB中的float值1应该是(0,0,255),RGB中的值0应该是(255,0,0),中间是(0,255,0)。我试图实现它,但在我的实现中,最高值是白色,最低值是黑色,这不是我想要实现的。
有人知道如何实现吗?
我的尝试是:
unsigned int rgb[] = {0,0,0};
//16581375 = 255^3
unsigned long colorValue = floatBetweenZeroAndOne * 16581375;
rgb[0] = colorValue %255;
rgb[1] = (colorValue / 255) % 255;
rgb[2] = ((colorValue / 255) / 255) % 255;
试试这个:
unsigned int rgb[] = { 0,0,0 };
float floatBetweenZeroAndOne = 0.25f;
if (floatBetweenZeroAndOne <= 0.5f)
{
floatBetweenZeroAndOne *= 2.0f;
rgb[0] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
rgb[1] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
}
else
{
floatBetweenZeroAndOne = floatBetweenZeroAndOne * 2.0f - 1.0f;
rgb[1] = (unsigned int)(255 * (1.0f - floatBetweenZeroAndOne) + 0.5f);
rgb[2] = (unsigned int)(255 * (floatBetweenZeroAndOne) + 0.5f);
}
它将平滑地在 R G B 分量之间插入 float
颜色值。
所以基本上你是说 rgb[0] 如果你的 float 变量是 0 应该是 0 如果你的变量是 1 它应该是 255。你的 float 变量 * 255 应该可以解决红色问题。从现在开始,让我们将您的浮点变量称为 floatValue。
现在让我们来做蓝色。这基本上与红色相反。我们希望当 floatValue 为 0 时蓝色为 255,当 floatValue 为 1 时蓝色为 0。您可以这样使用它:rgb[2] = 255 - floatValue * 255.
我猜绿色的是最棘手的。我们希望该值在 0 < floatValue < 0.5 时上升并在 0.5 < floatValue < 1 时下降。我认为 if 语句可以解决问题。
总的来说,我会这样编码。我没有测试过。
unsigned float floatValue = 0.236; // Completely random number between zero and one.
unsigned int rgb[] = {0,0,0};
rgb[0] = floatValue * 255;
rgb[2] = 255 - floatValue * 255;
if (floatValue > 0 && <= 0.5)
{
rgb[1] = floatValue * 512 // Since I guess you want it to be maxed out at 128.
}
else if (floatValue > 0.5 && floatValue <= 1)
{
rgb[1] = 255 - (floatValue - 0.5)*512;
}
else
{
cout << "floatValue has a value smaller than 0 or bigger than 1!";
return -1;
}
像这样的函数应该可以完成工作
void setColor(double value, int* rgb){
if(value > 1 || value < 0) return;
if(value > 0.5){
value -= 0.5;
rgb[0] = 0;
rgb[1] = (int)((1-2*value)*255);
rgb[2] = (int)(2*value*255);
}
if(value <= 0.5){
rgb[0] = (int)((1-2*value)*255);
rgb[1] = (int)(2*value*255);
rgb[2] = 0;
}
}
你也可以试试这个版本:
void rgbscalar(float scalar)
{
float ratio = 2 * scalar;
int r = 255 * (ratio - 1);
if ( r < 0 ) r = 0;
int b = 255 * (1 - ratio);
if ( b < 0 ) b = 0;
int g = 255 - b - r;
if ( g < 0 ) g = 0;
std::cout << r << " " << g << " " << b << " : " << scalar << std::endl;
}
此代码是从颜色 1 到颜色 2 的通用线性渐变;您可以使用它来制作多个渐变,例如,红色到绿色和绿色到蓝色,并使用 c1 和 c2 之间的变化填充数组。
如果有人知道编写此代码的更好方法,请随时提出建议:)。
#include <cstdint> # Defines uint_fast32_t
#pragma GCC diagnostic push // GCC only
#pragma GCC diagnostic ignored "-Wconversion" // GCC only, disable bitfield warnings
//+------------------------------------------------------------------+
// Color
// Parameters c1 and c2 are ARGB Colors to Gradient into the return value
// Gradient and Alpha is a percentage from c1 towards c2, accepts any range, but anything out of [0; 1.0] is cut
// The return value of the function is guaranteed to be between [0xYY000000; 0xYYFFFFFF], even if the gradient is invalid, and YY equals to the Alpha between [0; 1.0] -> AA[0; 255] proportionally
//+------------------------------------------------------------------+
uint_fast32_t argbGradient(uint_fast32_t c1, uint_fast32_t c2, double gradient = 0.5, double alpha = 0.0)
{
uint_fast32_t c = 0x00000000;
// Red is at 0x000000##
// Green is at 0x0000##00
// Blue is at 0x00##0000
// Alpha is at 0x##000000
if(gradient > 1.0) gradient = 1.0;
else if (gradient < +0.0) gradient = +0.0;
if(alpha > 1.0) alpha = 1.0;
else if(alpha < +0.0) alpha = +0.0;
uint_fast32_t red1 = (c1 & 0xFF);
uint_fast32_t green1 = (c1 & 0xFF00) >> 8;
uint_fast32_t blue1 = (c1 & 0xFF0000) >> 16;
uint_fast32_t alpha1 = (c1 & 0xFF000000) >> 24;
uint_fast32_t red2 = (c2 & 0xFF);
uint_fast32_t green2 = (c2 & 0xFF00) >> 8;
uint_fast32_t blue2 = (c2 & 0xFF0000) >> 16;
uint_fast32_t alpha2 = (c2 & 0xFF000000) >> 24;
if (red1 > red2) c = ((uint_fast32_t) (red1 - ((double) (red1 - red2) * gradient))) & 0xFF;
else c = ((uint_fast32_t) (red1 + ((double) (red2 - red1) * gradient))) & 0xFF;
if (green1 > green2) c = ((((uint_fast32_t) (green1 - ((double) (green1 - green2) * gradient))) & 0xFF) << 8) + c;
else c = ((((uint_fast32_t) (green1 + ((double) (green2 - green1) * gradient))) & 0xFF) << 8) + c;
if (blue1 > blue2) c = ((((uint_fast32_t) (blue1 - ((double) (blue1 - blue2) * gradient))) & 0xFF) << 16) + c;
else c = ((((uint_fast32_t) (blue1 + ((double) (blue2 - blue1) * gradient))) & 0xFF) << 16) + c;
if (alpha1 > alpha2) c = ((((uint_fast32_t) (alpha1 - ((double) (alpha1 - alpha2) * alpha))) & 0xFF) << 24) + c;
else c = ((((uint_fast32_t) (alpha1 + ((double) (alpha2 - alpha1) * alpha))) & 0xFF) << 24) + c;
return c;
}
#pragma GCC diagnostic pop // GCC only, restore specifically disabled flags