На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! правила раздела Алгоритмы
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code.../code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке :)
Модераторы: Akina, shadeofgray
  
> Алгоритм получения цвета в RGBa
    Всем привет!

    Возникла вот какая задача. Пусть есть исходный цвет #xxxxxx. Нужно получить другой цвет #yyyyyy, где значения первого цвета и второго - произвольные.
    Для получения второго цвета из первого можно суммировать другие цвета, применяя при это прозрачность накладываемого цвета (или цветов).

    Простой пример:

    user posted image

    Очень важны следующие аспекты:

    1) Нельзя накладывать цвет вообще без прозрачности - задача теряет свой смысл
    2) Суммируемая прозрачность всех накладываемых цветов должна быть максимальной по возможности
    3) Каждый отдельный накладываемый цвет так же должен по максимуму быть прозрачным

    Понимаю, что формулы тут может и не быть. Но как такое решить итерациями хотя бы?
      Цитата Majestio @
      Нельзя накладывать цвет вообще без прозрачности - задача теряет свой смысл

      В таком случае при некоторых исходных данных задача будет нерешаемой. Как ни накладывай цвета, 0xFFFFFF не получишь.
      А вот если сформулировать задачу так: "получить второй цвет наложением цвета с максимально возможной прозрачностью", то можно и формулу найти, причём, хватит одного наложения в любом случае.
      Сообщение отредактировано: Mikle -
        Цитата Mikle @
        В таком случае при некоторых исходных данных задача будет нерешаемой. Как ни накладывай цвета, 0xFFFFFF не получишь.

        Согласен на 100%

        Цитата Mikle @
        А вот если сформулировать задачу так: "получить второй цвет наложением цвета с максимально возможной прозрачностью", то можно и формулу найти, причём, хватит одного наложения в любом случае.

        А вот тут .... вопрос. Смотри рассуждение. Если для получения результирующего цвета компоненту R надо наложить с прозрачностью 50%, компоненту G с прозрачностью 25%, то одним наложением не обойтись. Конечно могу ошибаться, поэтому и не спрашивал бы.

        Ну а кроме рассуждений, можешь помочь алгоритмом/формулой?
          А что насчет формул смешивания?

          ExpandedWrap disabled
            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 );


          Можно считать даже в целых числах, если соблюдать порядок действий.
          Сообщение отредактировано: macomics -
            Цитата Majestio @
            Если для получения результирующего цвета компоненту R надо наложить с прозрачностью 50%, компоненту G с прозрачностью 25%, то одним наложением не обойтись.

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

            Сейчас пообедаю, и прикину формулу.
            Сообщение отредактировано: Mikle -
              Вот на бейсике, "r, g, b, a" - цвет наложения. Проверил.
              ExpandedWrap disabled
                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
              Сообщение отредактировано: Mikle -
                Mikle, благодарю! Конечно Бейсик для меня - темный лес :lol: Но, верю, что асилю! :lol:

                Добавлено
                Цитата macomics @
                А что насчет формул смешивания?

                Мне бы работающий пример. А так ... :-? Где исходный цвет, где результирующий, а где налагаемый ... :-?
                  Цитата Majestio @
                  Бейсик для меня - темный лес

                  Там Long - это int32, Single - это float, "\" - целочисленное деление (при делении целых чисел обычным делением получается float).
                  При приравнивании float к целому идёт округление до ближайшего, а не нижнего целого.
                  Сообщение отредактировано: Mikle -
                    :good:
                      Цитата Majestio @
                      Мне бы работающий пример. А так ... :-? Где исходный цвет, где результирующий, а где налагаемый ...
                      А что не понятно из названия bkgnd = background = цвет фона = исходный; color = налагаемый/примешиваемый; приставки R,G,B,A = сокращения от Red, Green, Blut, Alpha = компоненты цвета. Разумеется смешивание исходного и налагаемого цветов производится по значению компонента Alpha у налагаемого цвета: 255-alpha = степень для исходного цвета, alpha = степень для налагаемого цвета; у результата компонент alpha копируется из исходного цвета.
                        У меня в прошлой жысти был учитель, он часто повторял "Не учи меня жить - помоги материально". "Учитель" (по автоделу УПК) не был обременен излишним интеллектом - был просто призером СССР по автогонкам. Я у него учился и сдавал вождение на "права класса Цэ". Жесткий был мужик. Выходили на "стоянку" зимой - он выжимал сцепление-тормоз на дублирующих педалях, крутил малеха руль, и как только машина уходила в пике, он доставал из бордочка курицу и спрашивал ... "хочешь ножку?" ... а потом, без паузы "... только выровняй машину из пике". Это я к чему ...

                        macomics, хочешь "ножку"? Напиши код на любом ЯП, но только не учи меня жить! Не вздумай тут обидицца мне - видишь, я тут все обстряпал по-доброму! :lol:
                          Цитата Majestio @
                          macomics, хочешь "ножку"? Напиши код на любом ЯП, но только не учи меня жить!
                          Окай
                          ExpandedWrap disabled
                            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: в формулах перепутал делитель и множитель. Можно было сразу догадаться почему не работают.
                          Сообщение отредактировано: macomics -
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0389 ]   [ 15 queries used ]   [ Generated: 4.02.23, 22:26 GMT ]