Russian Qt Forum
Октябрь 04, 2024, 00:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: операторы для ARGB  (Прочитано 32301 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Август 27, 2010, 16:18 »

Добрый день

Есть простая структура
Код
C++ (Qt)
struct ARGB {
...
float alpha, red, green, blue;
};
 
Как определить операторы для нее? Напр оператор +

Код
C++ (Qt)
friend ARGB operator + ( const ARGB & c1, const ARGB & c2 )
{
return ARGB(c1.alpha + c2.alpha, c1.red + c2.red, c1.green + c2.green, c1.blue + c2.blue);
}
 
Так вроде глупо, если с2.alpha = 0.0f, то с2.red никак влиять не должен. А тогда как?

Спасибо
Записан
Denjs
Гость
« Ответ #1 : Август 27, 2010, 16:44 »

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

http://www.cyberforum.ru/cpp-beginners/thread59084.html
http://programmersclub.ru/24/
« Последнее редактирование: Август 27, 2010, 16:46 от Denjs » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Август 27, 2010, 16:50 »

С синтаксисом проблем нет, я спрашиваю как сделать операторы чтобы они давали разумный/корректный результат. Пример:

Код
C++ (Qt)
ARGB c1, c2;
...
// теперь мне надо получить среднее значение
// хорошо бы записать так
ARGB average = (c1 + c2) * 0.5f;
 
Но что должен делать + ?
Записан
Denjs
Гость
« Ответ #3 : Август 27, 2010, 17:32 »

Простите тогда меня, но что делает тема с вопросом о принципах работы с цветом в различных цветовых пространствах, в техническом подфоруме "Qt > Общие вопросы" ?!  

кроме того "разумный/корректный результат" - это как?
вы имитируете смешение цветов как будто у вас множество слоев пленочек-цветофильтров? а какая пленочка у вас "выше"/ближе к наблюдателю? свет у вас насквось идет или отраженное освещение?

или вы "проецируете" на белое несколько изображений от нескольких проекторов?
или вы смешиваете краски, разбавленные водой для прозрачности ?

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

 да?

собственно как только вы поймете какой процесс вы хотите имитировать и приведете мысли в порядок - вам будет понятно как поступать с цветами. Вариантов много, важен часто также порядок "сложения цветов". Улыбающийся
« Последнее редактирование: Август 27, 2010, 18:01 от Denjs » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Август 27, 2010, 17:54 »

вы для начала сами определитесь что значит смешивать 2 цвета и какой процесс вы имитируете в програме ?
в гимпе-фотошопе например это многослойные типографские пленочки. да?
Наверное можно и так сказать, но можно взять и пример поближе к Qt/UI: gradient control, у каждого ключа цвет (RGB) и альфа (A). Как рисовать градиент? В любом случае известны исходные данные (2 или более ARGB) и вес каждого из них. Задача - уметь удобно находить среднее ARGB. Возникает везде где есть альфа канал, поэтому нет смысла рассказывать для чего мне это нужно  Улыбающийся
Записан
Denjs
Гость
« Ответ #5 : Август 27, 2010, 18:02 »

многослойные типографские пленочки. та пленочка которая выше, может полностью заместить нижеследующую.
как вариант например так: скажем, если одна красная пленочка red2 лежит поверх red1,  то цвет конечного фильтра из 2-х пленочек - типа "суммарный" цвет наверное будет таким:
red3 = ((1-alpfa2)*red1*alpfa1)+red2*аlpfa2

Суммарная прозрачность 2-х пленочек думаю будет выглядеть так (а-ля сложение верояностей):
alpfa3 = 1-(1-alpfa1)*(1-alpfa2);

аlpfa - коэфф интенсивности замещения предыдущего цвета. 0 - все прозрачно, 1 - цвет полностью замещает предыдущий.

естественно в операции надо добавить ограничения на значения, что бы прозрачность не выходилаза 1 и т.п.

или можно так
http://base.vingrad.ru/view/1512-Gradientnaya-zalivka-i-slozhenie-tsvetov

Наверное можно и так сказать, но можно взять и пример поближе к Qt/UI: gradient control, у каждого ключа цвет (RGB) и альфа (A). Как рисовать градиент? В любом случае известны исходные данные (2 или более ARGB) и вес каждого из них. Задача - уметь удобно находить среднее ARGB. Возникает везде где есть альфа канал, поэтому нет смысла рассказывать для чего мне это нужно  Улыбающийся
Давайте приводить мысли в порядок. Альфа - прозрачность - она не "существует сама по себе". она подразумевает цвет на который вы это все накладываете. Что бы по цвету фона, цвецу фильтра и прозрачности фильтра - рассчитать итоговый цвет. Заметьте - у фона - "нет прозрачности"...

Другое дело если вы хотите "просуммировать" 2 светофильтра. Важен порядок что за чем... приблизительно я прикинул как оно может быть выше, хотя это конечно не совсем то что происходило-бы на реальных пленочках... НО! задача суммирования 2-х цветных пленочек - она к отрисоке UI мало имеет отношения пока не появляется третий цвет... какой? фона. на октором вы будете это торисовывать.... что бы получить конечный цвет который вы отрисуете на мониторе....

имхо...


ещё раз давайте более конкретно - к какому процессу вы рисуете алгоритм и что хотите отрисовывать? ))) без понимания того что вы хотите сделать - вы ну никак не сможете понять как вам это сделать. увы)
« Последнее редактирование: Август 27, 2010, 18:25 от Denjs » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 28, 2010, 11:28 »

ещё раз давайте более конкретно - к какому процессу вы рисуете алгоритм и что хотите отрисовывать? )))
Простейший случай: есть "ребро" (2 точки) в каждой  из них задан ARGB. Найти (интерполировать) ARGB посередине. Это не имеет никакого отношения к "пленкам" (т.е. комбинациям слоев) - т.к. там результат зависит от порядка следования слоев и поэтому нет смысла делать операторы.

Найти среднее ARGB  я могу так

Код
C++ (Qt)
ARGB AverageARGB( const ARGB & c1, const ARGB & c2 )
{
 ARGB result;
 
// interpolate alpha
 result.a = (c1.a + c2.a) * 0.5f;
 
// interpolate premultiplied colours
 result.r = (c1,r * c1.a + c2.r * c2.a) * 0.5f;
 result.g = (c1,g * c1.a + c2.g * c2.a) * 0.5f;
 result.b = (c1,b * c1.a + c2.b * c2.a) * 0.5f;
 
// clip divider
 float divider = MAX(result.a, 1.0e-4f);
 
// unpremultiply RGB
 result.r /= divider;
 result.g /= divider;
 result.b /= divider;
 
 return result;
}
 
Однако пользоваться этим не очень удобно. Напр надо посчитать интерполяцию 3-х точек (ARGB в центре треугольника) или N точек или интерполировать точки с разными весами - и каждый раз приходится городить новую ф-цию. Вот я и спрашиваю - как бы сделать удобные ARGB операторы?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Август 30, 2010, 21:18 »

Цитировать
..а вдоль дороги покойнички с косами стоять.. И - тишина..
Я так понимаю стандартный набор знаний об альфа-канале закончился?  Улыбающийся
Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #8 : Сентябрь 01, 2010, 11:16 »

общая формула для микса цветов:

C3 = C1*(1-alpha1) + C2*alpha2,

где С - это R, G или B, или Y, U или V (Y'CbCr, если быть точнее)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Сентябрь 01, 2010, 12:19 »

общая формула для микса цветов:

C3 = C1*(1-alpha1) + C2*alpha2,
С этой формулой явно что-то не так: если alpha1 = 1.0f (максимальная) то выходит C1 никак не роялит?
Но это не имеет отношения к моему вопросу. Да, с помощью альфа мы можем видеть одно изображение "сквозь" другое, т.е. иметь "слои". Как их комбинировать я знаю, а спрашиваю о другом: как (удобно) интерполировать альфа и RGB для точек ОДНОГО слоя. Сожалею что натолкнулся на "барьер мЫшления"  Улыбающийся
Записан
Denjs
Гость
« Ответ #10 : Сентябрь 01, 2010, 12:34 »

Цитировать
С этой формулой явно что-то не так: если alpha1 = 1.0f (максимальная) то выходит C1 никак не роялит?
Гм... это как я понимаю вариант "смешения пленочек", когда мы через одну пленку смотри на другую.? хотя выглядит не совсем как мне это кажется верным...


И это не барьер мышления, это нежелание вами внятно и конкретнее на примерах описать конкретно операции которые вы хотите производить. Т.е. возвращаемся в описанному ещё несколько дней назад о необходимости описать процессы которые вы имитируемые.

Пока вы внятно описали только случай "точки на грани двух картинок".  я думал вы сами уже все решили?
что вам мешает брать среднее по каждому из каналов в этом случае?
Код:
  
  result.r = (c1.r + c2.r) * 0.5;
  result.g = (c1.g+ c2.g) * 0.5;
  result.b = (c1.b+ c2.b) * 0.5;
  result.a = (c1.a+ c2.a) * 0.5;
?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Сентябрь 01, 2010, 17:46 »

Пока вы внятно описали только случай "точки на грани двух картинок".  я думал вы сами уже все решили?
Причем здесь картинки? Есть треугольник, в каждом угле задано ARGB (прочитал из файла). Теперь мне надо разбить треугольник на несколько. Появляются новые точки, для них надо посчитать (интерполировать) новые ARGB используя исходные. Так понятно?

что вам мешает брать среднее по каждому из каналов в этом случае?
Код:
  
  result.r = (c1.r + c2.r) * 0.5;
  result.g = (c1.g+ c2.g) * 0.5;
  result.b = (c1.b+ c2.b) * 0.5;
  result.a = (c1.a+ c2.a) * 0.5;
?
Как сказано в первом посте темы, это очевидно неверно: с1.r никак не может внести 0.5f  в финальный result.r если c1.a = 0.0f
« Последнее редактирование: Сентябрь 01, 2010, 17:49 от Igors » Записан
Denjs
Гость
« Ответ #12 : Сентябрь 02, 2010, 10:04 »

Как сказано в первом посте темы, это очевидно неверно: с1.r никак не может внести 0.5f  в финальный result.r если c1.a = 0.0f
С чего бы ээто вдруг "очевидно"?! )))
совершенно не очевидно Подмигивающий особенно в общем случае.
Ещё раз: пока вы не оструктурируютесь и не сможете представить физические процессы, ну или хотя бы модели, которые моделируете - у вас ничего не выйдет. Как минимум потому что для разных процессов будут разные формулы.

Вообще, имхо, вы похоже "как-то не так" понимаете "RGB+прозрачность"...

Прозрачность не меняет цвет, она именно делает его "прозрачным", определяет как его смешивать с подложкой.... Вы же отчего-то предполагаете что альфа-канал может менять ваш цвет фильтра - (" с1.r никак не может внести 0.5f  в финальный result.r если c1.a = 0.0f")

Давайте на пальцах? подумаем так: с точки зрения "прозрачности" - отдельный цвет в сотаве RGB - сам по себе ничто, он кодируют только соотношения между друг другом и положение между черным и белым... с точки зрения Alpha - RGB - это единое целое, которое он делает прозрачным весь сразу, не меняя его цвета... и вот как и сколько там один цвет из смешиваемых вносит - 0.3 или 0.8 - это уже для альфа-канала не важно ...  

по поводу моделей обработки цвета:
Если вам не подходит моделирование "пленочек", то возможно другая модель будет ближе для вашего случая: смоделируйте смешение разбавляемых водой красок. Вода - это как эквивалент альфа-канала. Она (как и альфа-канал) не меняет цвет, она делает его прозрачным. Процент воды в растворе - это альфа-канал. А вот RGB - определяет соотношения в банке с краской, которая не разбавлена. Так для вас понятнее?

Вот представьте что вы смешиваете 2 раствора краски в равных пропорциях : один раствор, в котором 20 процентов воды, с другим раствором, в котором 50 процентов воды и разливаете его на подсвеченным снизу матовом стекле.

первый вопрос - сколько процентов воды будет в конечном растворе? праально - 35.
А сколько процентов краски будет в конечном растворе - праально. 65.
Надо расписывать, что количество краски в конечном растворе будет рассчитываться именно как  
 
Код:
result.r = (c1.r + c2.r) * 0.5
?
 
PS: (если совсем придираться, оно конечно не совсем удачно - для красок надо применять цветовое простванство CMYK или аналогичное (предназначенное для красок на белом), а мы в RGB остались... но думаю пока это не сильно существенно, тем более что само по себе понятие "прозрачность" , имхо, плохо подходит к пространству RGB которое моделирует смешение света в черном пространстве).. имхо...
« Последнее редактирование: Сентябрь 02, 2010, 12:00 от Denjs » Записан
vipet
Бывалый
*****
Offline Offline

Сообщений: 452


Просмотр профиля
« Ответ #13 : Сентябрь 02, 2010, 11:28 »

общая формула для микса цветов:

C3 = C1*(1-alpha1) + C2*alpha2,

где С - это R, G или B, или Y, U или V (Y'CbCr, если быть точнее)

Пардон, ошибся. Надо вот так:

C3 = C1*(1-Alpha) + C2*Alpha,

где
С - это R, G или B, или Y, U или V (Y'CbCr, если быть точнее)
Alpha - это прозрачность накладываемого цвета.

С1 - компоненты пикселя, на который накладывается пиксель с компонентами С2.

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Сентябрь 02, 2010, 16:58 »

Вообще, имхо, вы похоже "как-то не так" понимаете "RGB+прозрачность"...
Давайте разберемся  Улыбающийся

Вот представьте что вы смешиваете 2 раствора краски в равных пропорциях : один раствор, в котором 20 процентов воды, с другим раствором, в котором 50 процентов воды и разливаете его на подсвеченным снизу матовом стекле.

первый вопрос - сколько процентов воды будет в конечном растворе? праально - 35.
А сколько процентов краски будет в конечном растворе - праально. 65.
Надо расписывать, что количество краски в конечном растворе будет рассчитываться именно как  
 
Код:
result.r = (c1.r + c2.r) * 0.5
?
 
Давайте переведем "литры" в ARGB модель. Для красной краски имеем

1-литр  Red = 1.0f, Alpha = 0.8f
2-литр  Red = 1.0f, Alpha = 0.5f
--------------------------
смесь: Red = 1.0f, Alpha = 0.65f

Т.е. предложенная Вами модель никак не учитывает интенсивность самого R(G, B)

Надо вот так:

C3 = C1*(1-Alpha) + C2*Alpha,
Я против этого ничего не имею, но это просто смешивание с весом. Так рисуется напр непрозрачная подложка С1 позади полупрозрачного C2. Но это не подходит для смешивания 2-х компонент у каждого из которых своя альфа
Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.267 секунд. Запросов: 23.