Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[44.192.95.161] |
|
Сообщ.
#1
,
|
|
|
Всем привет!
Возникла вот какая задача. Пусть есть исходный цвет #xxxxxx. Нужно получить другой цвет #yyyyyy, где значения первого цвета и второго - произвольные. Для получения второго цвета из первого можно суммировать другие цвета, применяя при это прозрачность накладываемого цвета (или цветов). Простой пример: Очень важны следующие аспекты: 1) Нельзя накладывать цвет вообще без прозрачности - задача теряет свой смысл 2) Суммируемая прозрачность всех накладываемых цветов должна быть максимальной по возможности 3) Каждый отдельный накладываемый цвет так же должен по максимуму быть прозрачным Понимаю, что формулы тут может и не быть. Но как такое решить итерациями хотя бы? |
Сообщ.
#2
,
|
|
|
Цитата Majestio @ Нельзя накладывать цвет вообще без прозрачности - задача теряет свой смысл В таком случае при некоторых исходных данных задача будет нерешаемой. Как ни накладывай цвета, 0xFFFFFF не получишь. А вот если сформулировать задачу так: "получить второй цвет наложением цвета с максимально возможной прозрачностью", то можно и формулу найти, причём, хватит одного наложения в любом случае. |
Сообщ.
#3
,
|
|
|
Цитата Mikle @ В таком случае при некоторых исходных данных задача будет нерешаемой. Как ни накладывай цвета, 0xFFFFFF не получишь. Согласен на 100% Цитата Mikle @ А вот если сформулировать задачу так: "получить второй цвет наложением цвета с максимально возможной прозрачностью", то можно и формулу найти, причём, хватит одного наложения в любом случае. А вот тут .... вопрос. Смотри рассуждение. Если для получения результирующего цвета компоненту R надо наложить с прозрачностью 50%, компоненту G с прозрачностью 25%, то одним наложением не обойтись. Конечно могу ошибаться, поэтому и не спрашивал бы. Ну а кроме рассуждений, можешь помочь алгоритмом/формулой? |
Сообщ.
#4
,
|
|
|
А что насчет формул смешивания?
Asaved = bkgnd >> 24; Acolor = color >> 24; Abkgnd = 255 - Acolor; Rcolor = Acolor * ( color & 255 ) / 255; Rbkgnd = Abkgnd * ( bkgnd & 255 ) / 255 + Rcolor; Gcolor = Acolor * ((color >> 8 ) & 255 ) / 255; Gbkgnd = Abkgnd * ((bkgnd >> 8 ) & 255 ) / 255 + Gcolor; Bcolor = Acolor * (( color >> 16 ) & 255 ) / 255; Bbkgnd = Abkgnd * (( bkgnd >> 16 ) & 255 ) / 255 + Bcolor; result = ( Asaved << 24 ) | ( Bbkgnd << 16 ) | ( Gbkgnd << 8 ) | ( Rbkgnd ); Можно считать даже в целых числах, если соблюдать порядок действий. |
Сообщ.
#5
,
|
|
|
Цитата Majestio @ Если для получения результирующего цвета компоненту R надо наложить с прозрачностью 50%, компоненту G с прозрачностью 25%, то одним наложением не обойтись. Надо выбрать компонент, где нужна наибольшая альфа, а для остальных компонентов брать цвет заранее немного смикшированный. Сейчас пообедаю, и прикину формулу. |
Сообщ.
#6
,
|
|
|
Вот на бейсике, "r, g, b, a" - цвет наложения. Проверил.
Private Sub Form_Load() Dim c1 As Long, c2 As Long, c3 As Long Dim r1 As Long, g1 As Long, b1 As Long Dim r2 As Long, g2 As Long, b2 As Long Dim k As Single, t As Single Dim r As Byte, g As Byte, b As Byte, a As Byte c1 = &H987342 'Исходный цвет c2 = &H9A44D3 'Требуемый цвет b1 = c1 And &HFF&: g1 = (c1 And &HFF00&) \ &H100&: r1 = (c1 And &HFF0000) \ &H10000 b2 = c2 And &HFF&: g2 = (c2 And &HFF00&) \ &H100&: r2 = (c2 And &HFF0000) \ &H10000 If r2 < r1 Then t = 1 - r2 / r1 Else If r2 > r1 Then t = 1 - (255 - r2) / (255 - r1) Else t = 0 k = t If g2 < g1 Then t = 1 - g2 / g1 Else If g2 > g1 Then t = 1 - (255 - g2) / (255 - g1) Else t = 0 If k < t Then k = t If b2 < b1 Then t = 1 - b2 / b1 Else If b2 > b1 Then t = 1 - (255 - b2) / (255 - b1) Else t = 0 If k < t Then k = t If k > 0 Then r = Lerp(r1, r2, 1 / k) g = Lerp(g1, g2, 1 / k) b = Lerp(b1, b2, 1 / k) End If a = k * 255 c3 = r * &H10000 + g * &H100& + b Caption = "a=" & Hex(a) & " c3=" & Hex(c3) & " control res=" & Hex(AlphaBlend(c1, c3, a)) End Sub Private Function Lerp(v1 As Long, v2 As Long, a As Single) As Long Lerp = v1 * (1 - a) + v2 * a End Function |
Сообщ.
#7
,
|
|
|
Mikle, благодарю! Конечно Бейсик для меня - темный лес Но, верю, что асилю!
Добавлено Цитата macomics @ А что насчет формул смешивания? Мне бы работающий пример. А так ... Где исходный цвет, где результирующий, а где налагаемый ... |
Сообщ.
#8
,
|
|
|
Цитата Majestio @ Бейсик для меня - темный лес Там Long - это int32, Single - это float, "\" - целочисленное деление (при делении целых чисел обычным делением получается float). При приравнивании float к целому идёт округление до ближайшего, а не нижнего целого. |
Сообщ.
#9
,
|
|
|
|
Сообщ.
#10
,
|
|
|
Цитата Majestio @ А что не понятно из названия bkgnd = background = цвет фона = исходный; color = налагаемый/примешиваемый; приставки R,G,B,A = сокращения от Red, Green, Blut, Alpha = компоненты цвета. Разумеется смешивание исходного и налагаемого цветов производится по значению компонента Alpha у налагаемого цвета: 255-alpha = степень для исходного цвета, alpha = степень для налагаемого цвета; у результата компонент alpha копируется из исходного цвета. Мне бы работающий пример. А так ... Где исходный цвет, где результирующий, а где налагаемый ... |
Сообщ.
#11
,
|
|
|
У меня в прошлой жысти был учитель, он часто повторял "Не учи меня жить - помоги материально". "Учитель" (по автоделу УПК) не был обременен излишним интеллектом - был просто призером СССР по автогонкам. Я у него учился и сдавал вождение на "права класса Цэ". Жесткий был мужик. Выходили на "стоянку" зимой - он выжимал сцепление-тормоз на дублирующих педалях, крутил малеха руль, и как только машина уходила в пике, он доставал из бордочка курицу и спрашивал ... "хочешь ножку?" ... а потом, без паузы "... только выровняй машину из пике". Это я к чему ...
macomics, хочешь "ножку"? Напиши код на любом ЯП, но только не учи меня жить! Не вздумай тут обидицца мне - видишь, я тут все обстряпал по-доброму! |
Сообщ.
#12
,
|
|
|
Цитата Majestio @ Окайmacomics, хочешь "ножку"? Напиши код на любом ЯП, но только не учи меня жить! ColorMixer: virtual at ebp-.loc_len label .loc .loc_len = ( 0 - 4 ) and ( $ - .loc + 3 ) rd 5 label .arg label .bkgnd dword ; Исходный цвет в формате RGBA (цвет фона) .Rb db ? .Gb db ? .Bb db ? .Ab db ? label .color dword ; Смешиваемый цвет .Rc db ? .Gc db ? .Bc db ? .Ac db ? .arg_len = ( 0 - 4 ) and ( $ - .arg + 3 ) end virtual push edi push esi push ebx push ebp mov ebp, esp if ~ .loc_len = 0 lea esp, [.loc] end if mov ebx, 255 mov eax, [.bkgnd] sub bl, [.Ac] movzx ecx, ah and eax, 0x00FF00FF mul ebx imul ecx, ebx mov esi, eax mov edi, ecx movzx ebx, [.Ac] mov eax, [.color] movzx ecx, ah and eax, 0x00FF00FF mul ebx imul ecx, ebx mov ebx, 255 add eax, esi add ecx, edi div ebx xchg eax, ecx xor edx, edx div ebx mov ah, cl bswap eax mov al, [.Ab] bswap eax leave pop ebx pop esi pop edi if .arg_len = 0 retn else retn .arg_len end if ADD: в формулах перепутал делитель и множитель. Можно было сразу догадаться почему не работают. |