Форум: "Основная";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];
ВнизЦвет Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.054 c