В этой статье я решил описать один вариант создания своего диалога выбора
цвета. Диалог выбора цвета, описанный в этой статье немного напоминает
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.
Вот и всё. Конечно, для крутого графического редактора этого
мало, но ведь можно и дополнить чем-нибудь ещё!
|