Создание своего диалога выбора цвета

В этой статье я решил описать один вариант создания своего диалога выбора цвета. Диалог выбора цвета, описанный в этой статье немного напоминает Photoshop-овский (но не совсем). Для лучшего взаимопонимания рекомендую скачать сначала исходник.


В общем приступим! Сначала создаём форму и помещаем туда всё необходимое:
77 компонентов типа TImage и назовём их так:

MainViewer – экран вывода градиента;
ScalKontr – определяет присутствие изменяемого компонента RGB цвета в градиенте (если выбран R_GB - то красного, если G_RB – то зелёного, если B_RG – то синего) от 0 до 255, путем нажатия курсора на нужную область.
Yarcost – шкала яркости выбранного оттенка.
Proba 1 – для выода цвета, находящегося под курсором при выборе насыщенности компонентом ScalKontr.
Proba 2 – для вывода оттенка, находящегося под курсором при выборе результата и яркости с помощью MainViewer или Yarcost.
ImageZahvat – для вывода выбранной в ScalKontr насыщенности.
Itog – для вывода выбранного оттенка.
12 Edit-ов, 3 RadioButton и 2 кнопки . Их оставим в покое (в смысле не переименовываем).

Теперь нам необходимо определиться с необходимыми процедурами.

Во-первых – это процедура генерирования шкалы контраста.

ВВо-вторых – это процедура генерирования градиента в MainViewer (в соответствии с выбранным типом градиента и выбранной насыщенностью).

В-третьих – процедура генерирования шкалы яркости, в соответствии с выбранным оттенком.

ННачнём с первого. Сам нижеприведённый код я поместил в обработчик OnCreate формы.

Пояснения смотрите в комментариях к коду:


var   
  LineColor, ViewColor: TColor;   
  ColR, ColG, ColB, i, j:integer;   
begin   
  {Если выбран баланс Красного с Синим и Зелёным (R_GB)}   
  if RadioButton1.Checked then   
  begin   
    ColR:=255;   
    ColG:=0;   
    ColB:=0;   
    for j:=0 to 255 do   
    begin   
      LineColor:=RGB(255-j, 0, 0); //Изменяем значение красного цвета   
      for i:=0 to 17 do   
        ScalKontr.Canvas.Pixels[i, j]:=LineColor; //рисуем точку   
    end;   
  end;   
   
    {Если выбран баланс Зелёного с Красным и Синим (G_RB)}   
  if RadioButton2.Checked then   
  begin   
    ColR:=0;   
    ColG:=255;   
    ColB:=0;   
    for j:=0 to 255 do   
    begin   
      LineColor:=RGB(0, 255-j, 0); //Изменяем значение зелёного  цвета   
      for i:=0 to 17 do   
        ScalKontr.Canvas.Pixels[i,j]:=LineColor; //рисуем точку   
    end;   
  end;   
   
    {Если выбран баланс Синего с Красным и Зелёным (B_RG)}   
  if RadioButton3.Checked then   
  begin   
    ColR:=0;   
    ColG:=0;   
    ColB:=255;   
    for j:=0 to 255 do   
    begin   
      LineColor:=RGB(0, 0, 255-j); //Изменяем значение синего цвета   
      for i:=0 to 17 do   
        ScalKontr.Canvas.Pixels[i,j]:=LineColor; //рисуем точку   
    end;   
  end;   
end;  

Думаю здесь всё понятно. Далее приступим к основной процедуре рисования градиента в MainViewer. Вот код:


procedure GenerateRGBInOutGrad(ClrOutR, ClrOutG, ClrOutB: Integer);   
var   
  i, j: Integer; //счётчики   
  PixelColor: TColor; //цвет пиксела   
  Holst: TBitMap; //Объект для записи пикселей   
begin   
  Holst:=TBitMap.Create; //создаём объект типа TBitMap   
  Holst.Width:=256; //указываем ширины   
  Holst.Height:=256; //указываем высоту   
   
  if ClrDialog.RadioButton1.Checked then //если выбрана RadioButton1   
  begin   
     {Палитра красного с зелёным и синим}   
    for j:=0 to 255 do //цикл по оси Y   
    begin   
      for i:=0 to 255 do //цикл по оси X   
      begin   
        PixelColor:=RGB(ClrOutR, j, i); {привязываем значения зелёного и синего к изменениям координат и переводим из 
RGB в TColor}   
        Holst.Canvas.Pixels[i, j]:=PixelColor; //Рисуем точку   
      end;  
    end;  
  end;  
   
  if ClrDialog.RadioButton2.Checked=true then //если выбрана RadioButton2   
  begin   
    {Палитра зелёного с красным и синим}   
    for j:=0 to 255 do //цикл по оси Y   
    begin   
      for i:=0 to 255 do //цикл по оси X   
      begin   
        PixelColor:=RGB(j, ClrOutG, i); {привязываем значения красного и синего к изменениям координат и переводим из 
RGB в TColor}   
        Holst.Canvas.Pixels[i, j]:=PixelColor; //Рисуем точку   
      end;  
    end;  
  end;  
   
  if ClrDialog.RadioButton3.Checked=true then //если выбрана RadioButton3   
  begin   
    {Палитра синего с красным и зелёным}   
    for j:=0 to 255 do //цикл по оси Y   
    begin   
      for i:=0 to 255 do //цикл по оси X  
      begin  
        PixelColor:=RGB(j, i, ClrOutB); {привязываем значения красного и зелёного к изменениям координат и переводим из 
RGB в TColor}   
        Holst.Canvas.Pixels[i, j]:=PixelColor; //Рисуем точку  
      end;  
    end;  
  end;  
   
  ClrDialog.MainViewer.Canvas.Draw(0,0,Holst); //рисуем всю картину на компонент TImage   
  Holst.Free; //освобождаем память, занимаемую объёктом Holst   
end;  

Вот!

Ну и, наконец, код вывода шкалы яркости:


{========================================================== Процедура генерации полосы яркости выбранного оттенка}  
procedure GenerYarkost(ColR, ColG, ColB: Real);   
var   
  i, j: integer; //счётчики   
  LineColor: TColor; //цвет TColor   
  StepR, StepG, StepB: Real; {шаг изменения для каждого цвета, необходимы для равномерного смешивания цветов по всей 
длине линии яркости. }  
begin  
  ClrDialog.Edit4.Text:=IntToStr(round(ColR));   {Эти строки}   
  ClrDialog.Edit5.Text:=IntToStr(round(ColG));   {нужны лишь в моём}   
  ClrDialog.Edit6.Text:=IntToStr(round(ColB));   {примере. В Вашем может и не понадобятся.}   
   
  {Генерация шкалы яркости для выбранного оттенка}   
  StepR:=(256-ColR)/256; //определение шага для красного   
  StepG:=(256-ColG)/256; //определение шага для зелёного   
  StepB:=(256-ColB)/256; //определение шага для синего   
   
  j:=256; //здесь счётчику по Y-ку присваивается начальное значение   
  repeat  
      j:=j-1; {Цикл по Y-ку организован с помощью repeat until чтобы  
    организовать обратный отсчёт от 256 до 1. Это сделано  
    для того, чтобы заполнять шкалу не с верху вниз, а снизу  
    вверх (т.к. начальная точка экранных координат  
    расположена в верхнем правом углу.)}   
   
    ColR:=ColR+StepR; {В каждом переходе цикла по Y}   
    ColG:=ColG+StepG; {увеличиваем значение соответствующего цвета}   
    ColB:=ColB+StepB; {на соответствующий ему шаг.}   
    for i:=0 to 17 do   
    begin   
      {На всякий случай проверим значения цветов на вхождение в пределы 255}   
      if ColR>255 then ColR:=255;   
      if ColG>255 then ColG:=255;   
      if ColB>255 then ColB:=255;   
   
      LineColor:=RGB(round(ColR), round(ColG), round(ColB)); //Записываем оттенок   
      ClrDialog.Yarcost.Canvas.Pixels[i, j]:=LineColor; //Рисуем точку в компонент TImage   
    end;  
  until j=1;  
end;  

ВВот в принципе все необходимые процедуры для написания такого диалога. Всё остальное – дело техники и это вы найдёте в примере к статье. Правда есть ещё один момент, который необходимо описать – это перевод из TColor в RGB формат. Чисто для примера сделаем 3 переменные типа integer (пусть это будут ColR , ColG и ColB ) и одну переменную типа TColor (Например, ColTColor). Далее присвоим значение переменной ColTColor. Пусть это будет зелёный (clGreen). Ну и, наконец, выделим из этой переменной значения RGB компонентов в соответствующие переменные типа integer. Весь код:


procedure TestTColorToRGB;   
var   
  ColR, ColG, ColB: integer;   
  ColTColor: TColor;   
begin   
  ColTColor:=clGreen; //присваиваем зелёный цвет   
   
  ColR:= ColTColor mod $100; //выделяем красный   
  ColG:=( ColTColor div $100) mod $100; //выделяем зелёный   
  ColB:= ColTColor div $10000; //выделяем синий   
end;  

У переменных должны получиться следующие значения:


ColR = 0;  
ColG = 255;  
ColB = 0.  

Вот и всё. Конечно, для крутого графического редактора этого мало, но ведь можно и дополнить чем-нибудь ещё!
Теги:
выбор цвета
Добавлено: 07 Августа 2018 08:35:25 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...