forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Наше Open Source Software (http://forum.boolean.name/forumdisplay.php?f=132)
-   -   Функции для преобразования RGB >> HSV (http://forum.boolean.name/showthread.php?t=16153)

ProgrammerForever 08.01.2012 12:54

Функции для преобразования RGB >> HSV
 
00h: Intro;
Добрый день. Вот решил поделиться первой наработкой на MP.
Эти процедуры преобазуют цвета из более удобного для человека HSV в
привычный для программиста RGB.

01h: Теория;
HSV - цветовая модель, использующая вместо удобных для техники RGB-компонент другие параметры: тон, насыщенность и яркость.
H - цвет. Может быть от 0 до 360. Задаёт общий оттенок.
S - чистота цвета. Может быть от 0 до 1. Чем S выше, тем полученный цвет насыщенней, чем меньше, тем ближе к нейтрально серому.
V - яркость. Может быть от 0 до 1. Чем ближе к 1, тем светлее оттенок.

Подробнее тут:
** http://ru.wikipedia.org/wiki/HSV_(цветовая_модель)
** http://en.wikipedia.org/wiki/HSL_and_HSV

Прототипы функций для получения RGB-компонент цвета выглядят так:
Function RFromHSV(intH,intS,intV:integer):integer;
Function GFromHSV(intH,intS,intV:integer):integer;
Function BFromHSV(intH,intS,intV:integer):integer;
, где
intH,intS,intV - исходные цвета в HSV, задаются в диапазоне [0..255]

02h: Практика;
Казалось бы, к чему такие изощрения, если есть RGB? По крайней мере, одно применение я нашёл.
Краткий алгоритм такой:
1) Получаем базовый цвет (H-компонента);
2) Рисуем фон этим цветом (H), при этом используем среднюю чистоту цвета и яркость.
3) Повышаем яркость и чистоту цвета процентов на 50. Рисуем элементы интерфейса (кнопки, например). H остаётся тем же.
4) Ещё раз повышаем яркость и чистоту цвета. Рисуем текст.

В результате получается такой эффект: при смене базового цвета остальные цвета получаются автоматически, притом смотрятся довольно гармонично, кнопки просматриваются и надписи всегда читаемы. Примерно то же самое можно наблюдать в Windows Media Player'е последних версий при смене цвета скина.
03h: Скриншоты;


04h: Код модуля:;
Код:

unit HSV2RGB;

interface

Function RFromHSV(intH,intS,intV:integer):integer;
Function GFromHSV(intH,intS,intV:integer):integer;
Function BFromHSV(intH,intS,intV:integer):integer;

implementation

Function RFromHSV(intH,intS,intV:integer):integer;
var
  intHi,intMin,intMax,intReturn:integer;
begin
{Функция для получения красной компоненты из HSV цвета}
{intH - тон. [0..255]}
{intS - насыщенность. [0..255]}
{intV - яркость. [0..255]}
{ProgrammerForever (C) 2012}
{Автор - Боев Григорий}

      intHi:=(intH/60) mod 6;
      intMin:=intV*(255-intS)/255;
      intMax:=intV;

      if (intHi=0) Then intReturn:=intMax;
      if (intHi=1) Then intReturn:=intMax-(intMax-intMin)*(intH mod 60)/60;
      if (intHi=2) Then intReturn:=intMin;
      if (intHi=3) Then intReturn:=intMin;
      if (intHi=4) Then intReturn:=intMin+(intMax-intMin)*(intH mod 60)/60;
      if (intHi=5) Then intReturn:=intMax;

      if (intReturn>255) then intReturn:=255;
      if (intReturn<0)  then intReturn:=0;
      RFromHSV:=intReturn;
end;


Function GFromHSV(intH,intS,intV:integer):integer;
var
  intHi,intMin,intMax,intReturn:integer;
begin
{Функция для получения зелёной компоненты из HSV цвета}
{intH - тон. [0..255]}
{intS - насыщенность. [0..255]}
{intV - яркость. [0..255]}
{ProgrammerForever (C) 2012}
{Автор - Боев Григорий}

      intHi:=(intH/60) mod 6;
      intMin:=intV*(255-intS)/255;
      intMax:=intV;

      if (intHi=0) Then intReturn:=intMin+(intMax-intMin)*(intH mod 60)/60;
      if (intHi=1) Then intReturn:=intMax;
      if (intHi=2) Then intReturn:=intMax;
      if (intHi=3) Then intReturn:=intMax-(intMax-intMin)*(intH mod 60)/60;
      if (intHi=4) Then intReturn:=intMin;
      if (intHi=5) Then intReturn:=intMin;

      if (intReturn>255) then intReturn:=255;
      if (intReturn<0)  then intReturn:=0;
      GFromHSV:=intReturn;
end;


Function BFromHSV(intH,intS,intV:integer):integer;
var
  intHi,intMin,intMax,intReturn:integer;
begin
{Функция для получения синей компоненты из HSV цвета}
{intH - тон. [0..255]}
{intS - насыщенность. [0..255]}
{intV - яркость. [0..255]}
{ProgrammerForever (C) 2012}
{Автор - Боев Григорий}

      intHi:=(intH/60) mod 6;
      intMin:=intV*(255-intS)/255;
      intMax:=intV;

      if (intHi=0) Then intReturn:=intMin;
      if (intHi=1) Then intReturn:=intMin;
      if (intHi=2) Then intReturn:=intMin+(intMax-intMin)*(intH mod 60)/60;
      if (intHi=3) Then intReturn:=intMax;
      if (intHi=4) Then intReturn:=intMax;
      if (intHi=5) Then intReturn:=intMax-(intMax-intMin)*(intH mod 60)/60;

      if (intReturn>255) then intReturn:=255;
      if (intReturn<0)  then intReturn:=0;
      BFromHSV:=intReturn;
end;

end.

Приятной работы.:cool:

ABTOMAT 08.01.2012 14:22

Ответ: Функции для преобразования RGB >> HSV
 
Спасибо! Жаль что на тухлом Паскале сделано, надо будет как-нибудь переписать на Си-лайк.

HolyDel 08.01.2012 14:51

Ответ: Функции для преобразования RGB >> HSV
 
Код:

void rgb::hsl(unsigned char h,unsigned char s,unsigned char l)
{
        if(s==0)
        {
                r = l;
                g = l;
                b = l;
        }
        else
        {
                float fh = (float)h / 255.0f;
                float fs = (float)s / 255.0f;
                float fl = (float)l / 255.0f;

                float t1=0,t2=0;

                if(fs<0.5f)
                {
                        t2 = fl * (1.0f + fs);
                }
                else
                {
                        t2 = fl+fs - fl*fs;
                }

                t1 = 2.0f*fl - t2;

                float rt = fh + 1.0f / 3.0f;
                float gt = fh;
                float bt = fh - 1.0f / 3.0f;

                if(rt<0)
                        rt += 1.0f;
                if(rt>1)
                        rt -= 1.0f;

                if(gt<0)
                        gt += 1.0f;
                if(gt>1)
                        gt -= 1.0f;

                if(bt<0)
                        bt += 1.0f;
                if(bt>1)
                        bt -= 1.0f;
                //R
                if(6.0f*rt<1.0f)
                        rt = t1 + (t2-t1)*6.0f*rt;
                else if(2.0f*rt<1.0f)
                        rt = t2;
                else if(3.0f*rt<2.0f)
                        rt = t1 + (t2-t1)*6.0f*((2.0f / 3.0f)-rt);
                else
                        rt = t1;

                //G
                if(6.0f*gt<1.0f)
                        gt = t1 + (t2-t1)*6.0f*gt;
                else if(2.0f*gt<1.0f)
                        gt = t2;
                else if(3.0f*gt<2.0f)
                        gt = t1 + (t2-t1)*6.0f*((2.0f / 3.0f)-gt);
                else
                        gt = t1;

                //B
                if(6.0f*bt<1.0f)
                        bt = t1 + (t2-t1)*6.0f*bt;
                else if(2.0f*bt<1.0f)
                        bt = t2;
                else if(3.0f*bt<2.0f)
                        bt = t1 + (t2-t1)*6.0f*((2.0f / 3.0f)-bt);
                else
                        bt = t1;

                r = (unsigned char)(rt * 255.0f);
                g = (unsigned char)(gt * 255.0f);
                b = (unsigned char)(bt * 255.0f);
        }
}


ProgrammerForever 08.01.2012 14:52

Ответ: Функции для преобразования RGB >> HSV
 
Тут писать-то нечего, в принципе.. Из диаграммы на Вики видно как зависят RGB от HSV. По ней, кстати, и сделал алгоритм. Вот только недопонял сам алгоритм на Вики: конкретно не понял f = H/60 - [H/60]


Часовой пояс GMT +4, время: 12:10.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot