к оглавлению

Вводный курс компьютерной графики

Процедуры преобразования моделей цветов

В данном приложении приведены процедуры перевода из RGB в HSV и наоборот и процедуры перевода из RGB в HLS и наоборот, соответствующие процедурам из [Род89] и [Фол85]. В процедурах используется вещественная арифметика. Переход на целочисленную арифметику, более подходящую для реальных применений, может быть выполнен определением констант для максимальных значений координат цвета - R,G,B, оттенка (hue), насыщенности (saturation), светлоты (value или lightness) и соответствующей модификацией текстов процедур.

/*==================================================== RGB_HSV
 * Преобразования из модели HSV в RGB и наоборот
 */

#include <stdio.h>

#define UNDEFINED -1.0  /* Неопределенное значение для Hue */

0.14.1  V_HSVRGB - перевод из HSV в RGB

/*--------------------------------------------------- V_HSVRGB
 * Переводит из модели HSV в модель RGB
 *
 * void V_HSVRGB (float *r,  float *g,  float *b,
 *                float hue, float sat, float val)
 *
 * Вход:
 * 0 <= hue <= 360 градусов - оттенок. Основные цвета:
 *                        0 - красный,  60 - желтый,
 *                      120 - зеленый, 180 - голубой
 *                      240 - синий,   300 - пурпурный
 *                     Остальные цвета между ними
 * 0.0 <= sat <= 1.0 - Saturation - насыщенность
 * 0.0 <= val <= 1.0 - Value - светлота
 *
 * Выход:
 * 0.0 <= r,g,b <= 1.0 - значения красного, зеленого, синего
 * V_HSVRGB= 0 - норма
 *           1/2/3 - ошибка в hue/ошибка в sat/ошибка в val
 */

int  V_HSVRGB (r, g, b, hue, sat, val)
float *r, *g, *b, hue, sat, val;
{  int  ii, otw;
   float c1, c2, c3, fr;

   otw= 0;
   if (sat == 0.0) {            /* Ахроматический цвет */
      *r= val;  *g= val;  *b= val;
      if (hue != UNDEFINED) ++otw;
   } else {                     /* Хроматический цвет  */
      hue-= (ii= (int)(hue/360.0)) * 360.0;
      if (ii < 0) hue= -hue;
      ii= (int)(hue /= 60.0);
      fr= hue - ii;
      c1= val*(1.0 - sat);
      c2= val*(1.0 - sat*fr);
      c3= val*(1.0 - sat*(1.0 - fr));
      switch (ii) {
         case 0: *r= val; *g= c3;  *b= c1;  break;
         case 1: *r= c2;  *g= val; *b= c1;  break;
         case 2: *r= c1;  *g= val; *b= c3;  break;
         case 3: *r= c1;  *g= c2;  *b= val; break;
         case 4: *r= c3;  *g= c1;  *b= val; break;
         case 5: *r= val; *g= c1;  *b= c2;  break;
      }
   }
   return (otw);
}  /* V_HSVRGB */

0.14.2  V_RGBHSV - перевод из RGB в HSV

/*--------------------------------------------------- V_RGBHSV
 * Переводит из модели RGB в модель HSV
 *
 * void V_RGBHSV (float r,  float g,  float b,
 *                float *hue, float *sat, float *val)
 *
 * Вход:
 * 0.0 <= r,g,b <= 1.0 - значения красного, зеленого, синего
 *
 *
 * Выход:
 * 0 <= hue <= 360 градусов - оттенок. Основные цвета:
 *                       0 - красный,  60 - желтый,
 *                     120 - зеленый, 180 - голубой
 *                     240 - синий,   300 - пурпурный
 *                     Остальные цвета между ними
 * 0.0 <= sat <= 1.0 - Saturation - насыщенность
 * 0.0 <= val <= 1.0 - Value - светлота
 *
 * V_RGBHSV= 0 - норма
 *           1/2/3 - ошибка в r/ошибка в g/ошибка в b
 */

int  V_RGBHSV (r, g, b, hue, sat, val)
float r, g, b, *hue, *sat, *val;
{  int  otw;
   float minc, maxc, h, s, v, dmax, rc, gc, bc;

   otw= 0;
   if (r < 0.0 || r > 1.0) ++otw;    /* Проверки значений   */
   if (g < 0.0 || g > 1.0) otw= 2;
   if (b < 0.0 || b > 1.0) otw= 3;
   if (!otw) {
      if ((maxc= r) < b) maxc= b;    /* Поиск макс значения */
      if (maxc < g) maxc= g;
      if ((minc= r) > b) minc= b;    /* Поиск мин  значения */
      if (minc > g) minc= g;
      s= 0.0;                        /* Насыщенность        */
      if (maxc != 0.0) s= (maxc-minc)/maxc;
      if (s == 0.0) h= UNDEFINED;    /* Ахроматический цвет */
      else {                         /* Хроматический  цвет */
         dmax= maxc-minc;
         rc= (maxc-r)/dmax;          /* rc - удаленность    */
         gc= (maxc-g)/dmax;          /* цвета от красного   */
         bc= (maxc-b)/dmax;
         if (r == maxc) h= bc-gc; else   /* Цвет между жел- */
                                         /* тым и пурпурным */
         if (g == maxc) h= 2+rc-bc; else /* Цвет между голу-*/
                                         /* бым и желтым    */
         h= 4+gc-rc;                     /* Цвет между пур- */
                                         /* пурным и голубым*/
         if ((h*= 60.0) < 0.0) h+= 360.0;
      }
      *hue= h;  *sat= s;  *val= maxc;
   }
   return (otw);
}  /* V_RGBHSV */

0.14.3  Тест процедур V_HSVRGB и V_RGBHSV

/*----------------------------------------------- MAIN RGB_HSV
 * Тестовая программа проверки прдпрограмм
 * преобразований из системы HSV в RGB и наоборот.
 */

void main(void)
{  int  ii;
   float r, g, b, r1, g1, b1, hue, sat, val;

   r= 0.0;  g= 0.0;  b= 0.0;  hue= 0.0;

m0:printf ("HSV r,g,b= (%f %f %f) ? ", r,g,b);
   scanf  ("%f%f%f", &r, &g, &b);
   ii= V_RGBHSV (r, g, b, &hue, &sat, &val);
   printf ("V_RGBHSV: otw=%d hue=%f sat=%f val=%f\n",
                      ii, hue, sat, val);
   ii= V_HSVRGB (&r1, &g1, &b1, hue, sat, val);
   printf ("V_HSVRGB: otw=%d r=%f g=%f b=%f\n",
                      ii, r1, g1, b1);
   goto m0;
}

/*==================================================== RGB_HLS
 * Преобразования из модели HLS в RGB и наоборот
 */

#include <stdio.h>

#define UNDEFINED -1.0  /* Неопределенное значение для Hue */

0.14.4  V_HLSRGB - перевод из HLS в RGB

/*--------------------------------------------------- V_HLSRGB
 * Переводит из модели HLS в модель RGB
 *
 * void V_HLSRGB (float *r,  float *g,  float *b,
 *                float hue, float sat, float lig)
 *
 * Вход:
 * 0 <= hue <= 360 градусов - оттенок. Основные цвета:
 *                       0 - красный,  60 - желтый,
 *                     120 - зеленый, 180 - голубой
 *                     240 - синий,   300 - пурпурный
 *                     Остальные цвета между ними
 * 0.0 <= sat <= 1.0 - Saturation - насыщенность
 * 0.0 <= lig <= 1.0 - Value - светлота
 *
 * Выход:
 * 0.0 <= r,g,b <= 1.0 - значения красного, зеленого, синего
 * V_HLSRGB= 0 - норма
 *           1/2/3 - ошибка в hue/ошибка в sat/ошибка в lig
 */

static float VAL_RGB (n1, n2, hue)
float n1, n2, hue;
{  float otw;
   if (hue < 0)     hue+= 360.0;
   hue= hue - ((int)(hue/360.0)) * 360.0;
   if (hue < 60.0)  otw= n1+(n2-n1)*hue/60.0; else
   if (hue < 180.0) otw= n2;                  else
   if (hue < 240.0) otw= n1+(n2-n1)*(240.0-hue)/60.0; else
   otw= n1;
   return (otw);
}  /* VAL_RGB */


int  V_HLSRGB (r, g, b, hue, sat, lig)
float *r, *g, *b, hue, sat, lig;
{  int   otw;
   float m1, m2;

   otw= 0;
   if (sat == 0.0) {            /* Ахроматический случай */
      if (hue == UNDEFINED) {
         *r= lig;  *b= lig;  *g= lig;
      } else ++otw;
   } else {                     /* Хроматический случай */
      if ((m2= lig) > 0.5) m2= 1.0 - lig;
      m2= lig + sat*m2;
      m1= 2*lig - m2;
      *r= VAL_RGB (m1, m2, hue+120.0);
      *g= VAL_RGB (m1, m2, hue);
      *b= VAL_RGB (m1, m2, hue-120.0);
   }
   return (otw);
}  /* V_HLSRGB */

0.14.5  V_RGBHLS - перевод из RGB в HLS

/*--------------------------------------------------- V_RGBHLS
 * Переводит из модели RGB в модель HLS
 *
 * void V_RGBHLS (float r,  float g,  float b,
 *                float *hue, float *sat, float *lig)
 *
 * Вход:
 * 0.0 <= r,g,b <= 1.0 - значения красного, зеленого, синего
 *
 *
 * Выход:
 * 0 <= hue <= 360 градусов - оттенок. Основные цвета:
 *                       0 - красный,  60 - желтый,
 *                     120 - зеленый, 180 - голубой
 *                     240 - синий,   300 - пурпурный
 *                     Остальные цвета между ними
 * 0.0 <= sat <= 1.0 - Saturation - насыщенность
 * 0.0 <= lig <= 1.0 - Value - светлота
 *
 * V_RGBHLS= 0 - норма
 *           1/2/3 - ошибка в r/ошибка в g/ошибка в b
 */

int  V_RGBHLS (r, g, b, hue, sat, lig)
float r, g, b, *hue, *sat, *lig;
{  int  otw;
   float minc, maxc, h, s, l, dm, rc, gc, bc;

   otw= 0;
   if (r < 0.0 || r > 1.0) ++otw;
   if (g < 0.0 || g > 1.0) otw= 2;
   if (b < 0.0 || b > 1.0) otw= 3;
   if (!otw) {
      if ((maxc= r) < b) maxc= b;
      if (maxc < g) maxc= g;
      if ((minc= r) > b) minc= b;
      if (minc > g) minc= g;
      l= (maxc + minc) / 2;     /* Светлота */
      if (maxc == minc) {       /* r=g=b - ахроматический */
         s= 0.0;                /* случай */
         h= UNDEFINED;
      } else {                  /* Хроматический случай */
         dm= maxc-minc;
         s= (l < 0.5) ? dm/(maxc+minc) : dm/(2-maxc-minc);
         rc= (maxc-r)/dm;       /* Вычисление тона */
         gc= (maxc-g)/dm;       /* rc задает удаленность */
         bc= (maxc-b)/dm;       /* цвета от красного     */
         if (r == maxc) h= bc-gc;   else /* Цвет между жел- */
                                         /* тым и пурпурным */
         if (g == maxc) h= 2+rc-bc; else /* Цвет между голу-*/
                                         /* бым и желтым    */
         h= 4+gc-rc;                     /* Цвет между пур- */
                                         /* пурным и голубым*/
         if ((h*= 60.0) < 0.0) h+= 360.0;
      }
      *hue= h;  *sat= s;  *lig= l;
   }
   return (otw);
}  /* V_RGBHLS */

0.14.6  Тест процедур V_HLSRGB и V_RGBHLS

/*----------------------------------------------- MAIN RGB_HLS
 * Тестовая программа проверки подпрограмм
 * преобразований из системы HLS в RGB и наоборот.
 */

void main(void)
{  int  ii;
   float r, g, b, r1, g1, b1, hue, sat, lig;

   r= 0.0;  g= 0.0;  b= 0.0;  hue= 0.0;

m1:printf ("HLS r,g,b= (%f %f %f) ? ", r,g,b);
   scanf  ("%f%f%f", &r, &g, &b);
   ii= V_RGBHLS (r, g, b, &hue, &sat, &lig);
   printf ("V_RGBHLS: otw=%d hue=%f sat=%f lig=%f\n",
                      ii, hue, sat, lig);
   ii= V_HLSRGB (&r1, &g1, &b1, hue, sat, lig);
   printf ("V_HLSRGB: otw=%d r=%f g=%f b=%f\n",
                      ii, r1, g1, b1);
   goto m1;
}
к оглавлению

Знаете ли Вы, что в 1965 году два американца Пензиас (эмигрант из Германии) и Вильсон заявили, что они открыли излучение космоса. Через несколько лет им дали Нобелевскую премию, как-будто никто не знал работ Э. Регенера, измерившего температуру космического пространства с помощью запуска болометра в стратосферу в 1933 г.? Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution