Step 1: RGB to HSV;
Step 2: Blending;
Step 3: HSV to RGB.
Blends:
- The Hue blend mode preserves the luma and chroma of the bottom layer, while adopting the hue of the top layer.
- The Saturation blend mode preserves the luma and hue of the bottom layer, while adopting the chroma of the top layer.
- The Color blend mode preserves the luma of the bottom layer, while adopting the hue and chroma of the top layer.
- The Luminosity blend mode preserves the hue and chroma of the bottom layer, while adopting the luma of the top layer.
#define ROUND(x) ((int) ((x) + 0.5))
void rgb_to_hsv ( int *red,
int *green,
int *blue)
{
double r, g, b;
double h, s, v;
int min;
double delta;
r = *red;
g = *green;
b = *blue;
if (r > g)
{
v = max(r, b);
min = min(g, b);
}
else
{
v = max (g, b);
min = min (r, b);
}
delta = v - min;
if (v == 0.0)
s = 0.0;
else
s = delta / v;
if (s == 0.0)
{
h = 0.0;
}
else
{
if (r == v)
h = 60.0 * (g - b) / delta;
else if (g == v)
h = 120 + 60.0 * (b - r) / delta;
else
h = 240 + 60.0 * (r - g) / delta;
if (h < 0.0)
h += 360.0;
if (h > 360.0)
h -= 360.0;
}
*red = ROUND (h);
*green = ROUND (s * 255.0);
*blue = ROUND (v);
if (*red == 360)
*red = 0;
}
void hsv_to_rgb ( int *hue,
int *saturation,
int *value)
{
double h, s, v, h_temp;
double f, p, q, t;
int i;
if (*saturation == 0)
{
*hue = *value;
*saturation = *value;
*value = *value;
}
else
{
h = *hue;
s = *saturation / 255.0;
v = *value / 255.0;
if (h == 360)
h_temp = 0;
else
h_temp = h;
h_temp = h_temp / 60.0;
i = floor (h_temp);
f = h_temp - i;
p = v * (1.0 - s);
q = v * (1.0 - (s * f));
t = v * (1.0 - (s * (1.0 - f)));
switch (i)
{
case 0:
*hue = ROUND (v * 255.0);
*saturation = ROUND (t * 255.0);
*value = ROUND (p * 255.0);
break;
case 1:
*hue = ROUND (q * 255.0);
*saturation = ROUND (v * 255.0);
*value = ROUND (p * 255.0);
break;
case 2:
*hue = ROUND (p * 255.0);
*saturation = ROUND (v * 255.0);
*value = ROUND (t * 255.0);
break;
case 3:
*hue = ROUND (p * 255.0);
*saturation = ROUND (q * 255.0);
*value = ROUND (v * 255.0);
break;
case 4:
*hue = ROUND (t * 255.0);
*saturation = ROUND (p * 255.0);
*value = ROUND (v * 255.0);
break;
case 5:
*hue = ROUND (v * 255.0);
*saturation = ROUND (p * 255.0);
*value = ROUND (q * 255.0);
break;
}
}
}
{
rgb_to_hsv(rs, gs, bs);
rgb_to_hsv(rd, gd, bd);
*gs = *gd;
*bs = *bd;
}
{
rgb_to_hsv(rs, gs, bs);
rgb_to_hsv(rd, gd, bd);
*rs = *rd;
*bs = *bd;
}
//Tests
void saturationTest(){
int sr = (int)(0x55);
int sg = (int)(0x66);
int sb = (int)(0x77);
int dr = (int)0xAA;
int dg = (int)0xFF;
int db = (int)0x99;
int bgr = dr;
int bgg = dg;
int bgb = db;
float a = 0.5f;
void hueTest(){
int sr = (int)(0x55);
int sg = (int)(0x66);
int sb = (int)(0x77);
int dr = (int)0xAA;
int dg = (int)0xFF;
int db = (int)0x99;
int bgr = dr;
int bgg = dg;
int bgb = db;
float a = 0.25f;
hueLayers(&sr, &sg, &sb, &dr, &dg, &db);
printf(" HUE Blend = #%02X %02X %02X \n", sr, sg, sb);
}
int sg = (int)(0x66);
int sb = (int)(0x77);
int dg = (int)0xFF;
int db = (int)0x99;
int bgg = dg;
int bgb = db;
satLayers(&sr, &sg, &sb, &dr, &dg, &db);
printf(" SaturationBlend = #%02X %02X %02X \n", sr, sg, sb);
}int sg = (int)(0x66);
int sb = (int)(0x77);
int dg = (int)0xFF;
int db = (int)0x99;
int bgg = dg;
int bgb = db;
printf(" HUE Blend = #%02X %02X %02X \n", sr, sg, sb);
}
Комментариев нет:
Отправить комментарий