Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.28;
Скачать: CL | DM;

Вниз

Цвет   Найти похожие ветки 

 
nexxiss ©   (2004-03-04 12:57) [0]

Имеется цвет ( допустим темно-бежевый ), необходимо преобразовать его ( в светло-бежевый ). Как этого можно достич.


 
YurikGl ©   (2004-03-04 13:29) [1]

Один из вариантов решения.

Можно получить доступ к каждому цветовому каналу
rgbcolor:TColor

GetGValue(RGBColor) - зеленый канал
GetRValue(RGBColor) - красный канал
GetBValue(RGBColor) - голубой канал

уменьшаешь значения каждого канала

потом собираешь цвет обратно

bm.Canvas.Pixels[x,y]:=r+g*256+b*65536+(rgbcolor div (256*256*256));

Это выдрано из рабочего кода

r,g,b - насыщенность каждого цвета соответсвенно.

В принципе, вроде как можно добраться до показателя яркости цвета в целом и его изменить. Но как - я не знаю.
Покопайтесь в литературе по графике. Наверняка уменьшать нужно не просто пропорционально, а с какими-нибудь коэффициентами.


 
MBo ©   (2004-03-04 13:30) [2]

Если не заморачиваться с HSL,V цветовыми моделями, то просто умножить каждую составляющую R, G, B на какое-то число или прибавить сколько-то, ограничивая результат 255


 
nexxiss ©   (2004-03-04 16:25) [3]

Спасибо, попробую разобраться


 
WebErr ©   (2004-03-04 16:33) [4]


> bm.Canvas.Pixels[x,y]:=r+g*256+b*65536+(rgbcolor div (256*256*256));

Чо за бред! 8\
rgbcolor div (256*256*256) всегда =0!
А вместо r+g*256+b*65536 можно писать RGB(r, g, b)!!!


 
Семен Сорокин ©   (2004-03-04 16:34) [5]

{Понижает значение цвета aColor на aValue единиц (0..255)}
function ObscureColor(aColor: tColor; aValue: byte): tColor;
var
 _r, _g, _b: byte;
begin
_r := GetRValue(ColorToRGB(aColor));
_g := GetGValue(ColorToRGB(aColor));
_b := GetBValue(ColorToRGB(aColor));
if _r < aValue then
 _r := 0
else
 _r := _r - aValue;
if _g < aValue then
 _g := 0
else
 _g := _g - aValue;
if _b < aValue then
 _b := 0
else
 _b := _b - aValue;
Result := RGB(_r, _g, _b)
end;


 
YuRock ©   (2004-03-04 16:38) [6]

> Семен Сорокин ©   (04.03.04 16:34) [5]

Ну и что эта ф-ция даст? Она ж не пропорционально изменяет оттенки


 
WebErr ©   (2004-03-04 16:38) [7]


> Семен Сорокин ©   (04.03.04 16:34) [5]
> {Понижает значение цвета aColor на aValue единиц (0..255)}

Неа... !!! Лучше всего умножать на коэф. 0 <= k <= 1, так логичнее и проще! :)))


 
Семен Сорокин ©   (2004-03-04 16:43) [8]

YuRock ©   (04.03.04 16:38) [6]
Ну и что эта ф-ция даст? Она ж не пропорционально изменяет оттенки

довольно часто ей пользуюсь, при aValue in [15..75] именно эффект затемнения.


 
YuRock ©   (2004-03-04 16:43) [9]

> WebErr ©   (04.03.04 16:38) [7]

Тоже неверно.

Пример:

r=0
g=0
b=20

0 <= k <= 1

И как мне ярко-голубой цвет получить с помощью RGB(r*k, g*k, b*k)?


 
YuRock ©   (2004-03-04 16:46) [10]

> Семен Сорокин ©   (04.03.04 16:43) [8]
> именно эффект затемнения

На сколько я понимаю, автор хотел спросить: "Как не меняя оттенка изменить яркость?"

А Ваша ф-ция меняет оттенок...


 
WebErr ©   (2004-03-04 16:46) [11]

Можно плавно преобразовывать цвета из одного известного в другой приблизительно так:

function ColorLine(A, B: TColor; K: Double): TColor;
var
 rA, gA, bA: Byte;
 rB, gB, bB: Byte;
 rC, gC, bC: Byte;
begin
 rA := GetRValue(A);
 gA := GetGValue(A);
 bA := GetBValue(A);

 rB := GetRValue(B);
 gB := GetGValue(B);
 bB := GetBValue(B);

 rC := rA + Round(K* (rB - rA));
 gC := gA + Round(K* (gB - gA));
 bC := bA + Round(K* (bC - bA));

 Result := RGB(rC, gC, bC);
end;

Надеюсь написал без ошибок - писал на ходу! :))))


 
Семен Сорокин ©   (2004-03-04 16:48) [12]

пусть автор выбирает, вариантов много


 
WebErr ©   (2004-03-04 16:49) [13]


> YuRock ©   (04.03.04 16:43) [9]
> > WebErr ©   (04.03.04 16:38) [7]
>
> Тоже неверно.
>
> Пример:
>
> r=0
> g=0
> b=20
>
> 0 <= k <= 1
>
> И как мне ярко-голубой цвет получить с помощью RGB(r*k,
> g*k, b*k)?

Гы! Тоже мне гений! Я на графических модулях собаку съел!!! См. [11]. :))))


 
YuRock ©   (2004-03-04 16:51) [14]

> Можно плавно преобразовывать цвета из одного известного в другой

Не понял, зачем преобразовывать из одного известного в другой известный? Что это за Result := RGB(rC, gC, bC);? Что это за третий цвет? Я Чего-то не понял...


 
Семен Сорокин ©   (2004-03-04 16:54) [15]

2WebErr
лучше использовать еще и ColorToRGB:
GetRValue(ColorToRGB(A));
чтобы с системными константными цветами (clBtnFace, ...) тоже работало.


 
WebErr ©   (2004-03-04 16:56) [16]


> WebErr ©   (04.03.04 16:46) [11]
> Можно плавно преобразовывать цвета из одного известного
> в другой приблизительно так:
>
> function ColorLine(A, B: TColor; K: Double): TColor;

Разумеется K плавно изменяется от 0 до 1 за N+1 шагов! :))))
Т. е.

K := 0;
dK := 1/N;
for I := 0 to N do
begin
 // using ColorLine(A,B,K)
 K := K + dK;
end;


 
YuRock ©   (2004-03-04 17:00) [17]

> WebErr

Я все же не понял функцианальности ColorLine. Что она делает? Попрошу ответить на [14]...


 
WebErr ©   (2004-03-04 17:00) [18]


> YuRock ©   (04.03.04 16:51) [14]
> > Можно плавно преобразовывать цвета из одного известного
> в другой
>
> Не понял, зачем преобразовывать из одного известного в другой
> известный? Что это за Result := RGB(rC, gC, bC);? Что это
> за третий цвет? Я Чего-то не понял...

Гы-гы! Кто бы сомневался! :))))
А как ты думаешь, чего хочет сам автор? :))))
Прочитай вопрос ещё раз!
По сути C := A + K*(B-A), где С - это промежуточный цвет в некую единицу времени! :))))


 
WebErr ©   (2004-03-04 17:02) [19]


> По сути C := A + K*(B-A), где С - это промежуточный цвет
> в некую единицу времени! :))))

Где С, А, В - это просто 3D-вектора! :))))


 
YurikGl ©   (2004-03-04 17:14) [20]

Re: WebErr
Объясню, почему писал "rgbcolor div (256*256*256)" TColor все-же четырех-байтная величина. И четвертый байт, по крайней мере, если читать help не всегда равен 0. Можно, конечно, на него не обращать внимания, но все-же.


 
YuRock ©   (2004-03-04 17:20) [21]

> WebErr
> Кто бы сомневался

Итак. У меня есть цвет A (скажем, это серо-зеленый). Яркость равна 70%.

Автор спрашивал: "как из A сделать B, где B - это серо-зеленый цвет с яркостью, скажем 35%".

Как с помощью ColorLine это сделать? Как получить B = RGB(?,?,?) ?


 
WebErr ©   (2004-03-04 17:22) [22]


> YurikGl ©   (04.03.04 17:14) [20]
> Re: WebErr
> Объясню, почему писал "rgbcolor div (256*256*256)" TColor
> все-же четырех-байтная величина. И четвертый байт, по крайней
> мере, если читать help не всегда равен 0. Можно, конечно,
> на него не обращать внимания, но все-же.

Ясно, но не проще ли использовать макрос RGB(r, g, b)? :))))


 
YurikGl ©   (2004-03-04 17:23) [23]

Честно, этой функции не знал, было проще написать то что видишь :)


 
WebErr ©   (2004-03-04 17:28) [24]


> YurikGl ©   (04.03.04 17:23) [23]
> Честно, этой функции не знал, было проще написать то что
> видишь :)

:))))


 
YuRock ©   (2004-03-04 17:35) [25]

> WebErr
> :))))

Так как на счет [21]?


 
WebErr ©   (2004-03-04 17:49) [26]

LOL 35% - это K=0.35 и не приставай больше к взрослым дядям! :))))


 
YuRock ©   (2004-03-04 17:53) [27]

> WebErr ©   (04.03.04 17:49) [26]

Без комментариев...


 
WebErr ©   (2004-03-04 18:01) [28]


> YuRock ©   (04.03.04 17:20) [21]
> > WebErr
> > Кто бы сомневался
>
> Итак. У меня есть цвет A (скажем, это серо-зеленый). Яркость
> равна 70%.
>
> Автор спрашивал: "как из A сделать B, где B - это серо-зеленый
> цвет с яркостью, скажем 35%".
>
> Как с помощью ColorLine это сделать? Как получить B = RGB(?,?,?)
> ?

Тфу, Ё! 35% - это яркость!!! Sorry! Зачем тебе яркость, когда уже известны RGB обоих цветов, на крайняк есть формулы перевода из YMC модели (с твоей любимой яркостью) в RGB... YMC - это яркость и RB или GB не помню точно, но скорее всего яркость цвета просто не известна, в отличие от RGB-компонент, которые и задают 3DVector цвета - цвет по-любому 3D. :))))


 
YuRock ©   (2004-03-04 18:06) [29]

> WebErr ©   (04.03.04 18:01) [28]

> Зачем тебе яркость, когда уже известны RGB обоих цветов

Известны? По-моему, автор как раз спрашивает, как получить второй...

> на крайняк есть формулы перевода из YMC модели (с твоей любимой яркостью) в RGB

Э нет, уж, извините, на графике собаку съевший, есть формулы перевода из RGB в YMC (и то приблизительно работающие), а вот наоборот - хотелось бы посмотреть :))))


 
Gero ©   (2004-03-04 18:14) [30]

http://delphibase.endimus.com/?action=viewfunc&topic=mediacolors&id=10499


 
WebErr ©   (2004-03-04 18:15) [31]


> Э нет, уж, извините, на графике собаку съевший, есть формулы
> перевода из RGB в YMC (и то приблизительно работающие),
> а вот наоборот - хотелось бы посмотреть :))))

Формулы преобразования представляют собой линейную матрицу с ненулевым детерминантом (надеюсь знаешь, что это такое) => что обратное преобразование существует и оно единственно! :))))


 
WebErr ©   (2004-03-04 18:18) [32]

[31] ... => если просто изменить яркость, то переводим из RGB в яркость, меняем компонент яркости, а дальше идём на кухню и пьём чёрный кофе! :))))


 
WebErr ©   (2004-03-04 18:21) [33]

Если угодно, я даже сегодня посмотрю коэф-ты у матрицы перехода и завтра их продиктую, а вообще, если есть пособие В. Порева либо книга "Программирование SVGA-графики" (не помню, кто автор), то там всё энто есть - можете посмотреть и сами! :))))


 
YuRock ©   (2004-03-04 18:22) [34]

> WebErr ©   (04.03.04 18:15) [31]
> линейную матрицу с ненулевым детерминантом (надеюсь знаешь, что это такое)

Я когда-то матфак заканчивал, так что не надо рассказывать...

> WebErr ©   (04.03.04 18:15) [32]
> если просто изменить яркость, то переводим из RGB в яркость, меняем компонент яркости, а дальше идём на кухню и пьём чёрный кофе!

Если бы было все так просто, мне б не пришлось в свое время на этом свою собаку съесть...


 
WebErr ©   (2004-03-04 18:28) [35]


> Я когда-то матфак заканчивал, так что не надо рассказывать...

Я тоже оттуда! :)
> Если бы было все так просто, мне б не пришлось в свое время
> на этом свою собаку съесть...

А что же по твоему усложняет задачу питья кофе на кухне после изменения яркости, о, коллега по пожиранию собак?


 
YuRock ©   (2004-03-04 18:54) [36]

> WebErr ©   (04.03.04 18:28) [35]

1. Вопервых, я не понимаю, зачем для получения яркости использовать какие-то матрицы? Для этого можно воспользоваться такой готовой ф-цией:

type
 THLS = record
   H: Byte; // - оттенок
   L: Byte; // - яркость
   S: Byte; // - контраст
 end;

// Функция возвращает оттенок, яркость и контраст
function RGBToHLS(Color: Cardinal): THLS;
var
 R, G, B, cMax, cMin: Byte;
 H, L, S, Rdelta, Gdelta, Bdelta: Integer;
begin
 R := GetRValue(Color);
 G := GetGValue(Color);
 B := GetBValue(Color);

 cMax := Max(Max(R, G), B);
 cMin := Min(Min(R, G), B);
 L := Round(((cMax + cMin) * 240 + 255) / 510);
 
 if cMax = cMin then begin
   S := 0;
   H := cMax;
 end else begin
   if L <= 120 then
     S := Round((((cMax - cMin) * 240) + ((cMax + cMin) / 2)) / (cMax + cMin))
   else
     S := Round((((cMax - cMin) * 240) + ((510 - cMax - cMin) / 2) ) / (510 - cMax - cMin));
   
   Rdelta := Round((((cMax - R) * 40) + ((cMax - cMin) / 2)) / (cMax - cMin));
   Gdelta := Round((((cMax - G) * 40) + ((cMax - cMin) / 2)) / (cMax - cMin));
   Bdelta := Round((((cMax - B) * 40) + ((cMax - cMin) / 2)) / (cMax - cMin));
   
   if R = cMax then begin
     H := Bdelta - Gdelta;
   end else begin
     if G = cMax then
       H := 80 + Rdelta - Bdelta
     else
       H := 160 + Gdelta - Rdelta;
   end;
   
   if H < 0 then
     H := H + 240
   else if H > 240 then
     H := H - 240;
 end;

 Result.H := H;
 Result.L := L;
 Result.S := S;
end;

Эта ф-ция практически полностью выдрана из примера в апишном хелпе.

2. На счет кофе - я погорячился. Есть такая же ф-ция для перевода из HLS в RGB. Я просто вспомнил о другой проблеме, когда и это не помогло. Кстати, могу и эту ф-цию показать. Правда, на Си - переводить пока не надо было:

/* utility routine for HLStoRGB */
WORD HueToRGB(n1,n2,hue)
WORD n1;
WORD n2;
WORD hue;
{

  /* range check: note values passed add/subtract thirds of range */
  if (hue < 0)

     hue += HLSMAX;

  if (hue > HLSMAX)
     hue -= HLSMAX;

  /* return r,g, or b value from this tridrant */
  if (hue < (HLSMAX/6))
     return ( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) );
  if (hue < (HLSMAX/2))
     return ( n2 );
  if (hue < ((HLSMAX*2)/3))
     return ( n1 + (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6))
);
  else
     return ( n1 );
}

DWORD HLStoRGB(hue,lum,sat)
WORD hue;
WORD lum;
WORD sat;
{
  WORD R,G,B;                /* RGB component values */

  WORD  Magic1,Magic2;       /* calculated magic numbers (really!) */

  if (sat == 0) {            /* achromatic case */
     R=G=B=(lum*RGBMAX)/HLSMAX;
     if (hue != UNDEFINED) {
        /* ERROR */
     }
  }
  else  {                    /* chromatic case */
     /* set up magic numbers */
     if (lum <= (HLSMAX/2))
        Magic2 = (lum*(HLSMAX + sat) + (HLSMAX/2))/HLSMAX;
     else
        Magic2 = lum + sat - ((lum*sat) + (HLSMAX/2))/HLSMAX;

     Magic1 = 2*lum-Magic2;

     /* get RGB, change units from HLSMAX to RGBMAX */
     R = (HueToRGB(Magic1,Magic2,hue+(HLSMAX/3))*RGBMAX +
(HLSMAX/2))/HLSMAX;
     G = (HueToRGB(Magic1,Magic2,hue)*RGBMAX + (HLSMAX/2)) / HLSMAX;
     B = (HueToRGB(Magic1,Magic2,hue-(HLSMAX/3))*RGBMAX +
(HLSMAX/2))/HLSMAX;
  }

  return(RGB(R,G,B));
}

// © Microsoft


 
YuRock ©   (2004-03-04 19:05) [37]

> nexxiss

В [36], кстати, и кроется решение Вашей проблемы. Вам осталось лишь:

1. Перевести ф-цию HLStoRGB на Паскаль;
2. Воспользоваться готовой RGBToHLS (передав в нее Ваш исходный цвет);
3. Получив L(яркость) рассчитать (ч-з процентное соотношение: зная нужный процент яркости и понимая, что L должно удовлетворять условию 0<=L<=240, это будет сделать очень легко);
4. Подставить полученную L и старые H и S в ф-цию HLStoRGB - это и даст требуемый цвет.


 
nexxiss ©   (2004-03-05 03:59) [38]

Не ожидал такой долгой дискусии на мой вопрос. Интересно было прочесть ее. Над вашими советами призадумался, спасибо за дельную инфо-ию. Буду потрошить свою голову на предмет наличия умных мыслей по вашим выводам. Будет что-то новое по теме, сообщите если незатруднит.



Страницы: 1 вся ветка

Текущий архив: 2004.03.28;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.022 c
14-1078206753
raymond
2004-03-02 08:52
2004.03.28
WinXP... На системном логическом диске - файл hiberfil.sys


1-1078427265
VID
2004-03-04 22:07
2004.03.28
GetTickCount


11-1056821442
mox
2003-06-28 21:30
2004.03.28
Incompatible types: TEditOptions and TEditOption


11-1056796781
Vladimir Kladov
2003-06-28 14:39
2004.03.28
Нужно связаться с Roman Vorobets


3-1077171427
Василий
2004-02-19 09:17
2004.03.28
DBase и прерывания