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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Сложить два QPixmap  (Прочитано 6297 раз)
Ginger_Ministrel
Гость
« : Август 11, 2015, 07:05 »

Задача: есть несколько QPixmap одинакового размера с кусочками картинки на полностью прозрачном фоне. Нужно получить из них один суммарный. Есть ли какие-то стандартные функции, или нужно поточечно их совмещать, переведя в QImage?

И дополнительный вопрос: стоит ли это затрат в случае, если нужно получить QGraphicsPixmapItem в итоге, или дешевле и проще создать несколько айтемов и просто поставить один над другим на сцене?
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Август 11, 2015, 07:24 »

Рисуете QPainter'ом их друг на друге
Записан

deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #2 : Ноябрь 22, 2015, 00:57 »

А если нужно нарисовать значок произвольного цвета обведенный черной рамкой
Код:
    pix = QPixmap(QImageReader(":/mask.png").size());
    pix.fill(c);
    pix.setMask(QPixmap(":/mask.png").mask());
    QPainter p(&pix);
    p.drawPixmap(0,0,QPixmap(":/border.png"));
    p.end();
Так нормально или можно сделать более быстрый и правильный код? Недостаток - маска битовая(без градаций).

Можно ли закрасить картинку одним цветом не трогая альфа канал?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Ноябрь 22, 2015, 12:12 »

Так нормально или можно сделать более быстрый и правильный код?
Конечно можно. Напр здесь был бы очень к месту класс который проходится по всем пикселям и применяет к каждому заданный юзером функтор/лямбду. Но если это 1-2 операции для картинки 100x100 и меньше - следует стремиться к минимуму написанных строк, как у Вас
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #4 : Ноябрь 24, 2015, 08:28 »

Но если это 1-2 операции для картинки 100x100 и меньше - следует стремиться к минимуму написанных строк, как у Вас
Иконки в среднем 16х16, под сотню. Сделал в цикле, т.к. битовая маска(когда от альфа канала остается 2 значения) мне совсем не подходит.

Код:
inline QRgb mix(const QRgb &c1,const QRgb &c2) { // на первый цвет накладывает второй цвет (оба цвета с произвольной прозрачностью)
    int c1a(qAlpha(c1));
    int c2a(qAlpha(c2));
    int a = c2a + (255-c2a)*c1a/255;
    int r = c2a*qRed(c2)   + (255-c2a)*c1a*qRed(c1)/255;
    int g = c2a*qGreen(c2) + (255-c2a)*c1a*qGreen(c1)/255;
    int b = c2a*qBlue(c2)  + (255-c2a)*c1a*qBlue(c1)/255;
    return a? qRgba(r/a, g/a, b/a, a): 0; }

inline QRgb fillLeftAlpha(const QRgb &src,const QRgb &c) { // залить цветом, оставив альфаканал
    return (src & 0xFF000000) + (c & RGB_MASK); }

//цикл
for(int y=0; y<h; ++y) {
    QRgb *rowData = (QRgb*)img.scanLine(y);
    QRgb *rowB = (QRgb*)imgBorder.scanLine(y);

    for(int x=0; x<w; ++x) {
        QRgb &pixelData = rowData[x];
        pixelData = fillLeftAlpha(pixelData, cState[i]);
        pixelData = mix(pixelData, rowB[x]); }}
« Последнее редактирование: Ноябрь 24, 2015, 09:07 от deMax » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Ноябрь 24, 2015, 11:45 »

Код:
inline QRgb mix(const QRgb &c1,const QRgb &c2) { // на первый цвет накладывает второй цвет (оба цвета с произвольной прозрачностью)
    int c1a(qAlpha(c1));
    int c2a(qAlpha(c2));
    int a = c2a + (255-c2a)*c1a/255;
    int r = c2a*qRed(c2)   + (255-c2a)*c1a*qRed(c1)/255;
    int g = c2a*qGreen(c2) + (255-c2a)*c1a*qGreen(c1)/255;
    int b = c2a*qBlue(c2)  + (255-c2a)*c1a*qBlue(c1)/255;
    return a? qRgba(r/a, g/a, b/a, a): 0; }
Все верно, только mix - не очень удачное название, это вычитающая (subtractive) модель. с2 - front, c1 - back
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #6 : Ноябрь 26, 2015, 11:38 »

Все верно, только mix - не очень удачное название, это вычитающая (subtractive) модель. с2 - front, c1 - back
так вычитающая модель это например CMYK для печати или рисование на бумаге.

У меня алгоритм реализует Normal (Нормальный) режим наложения или смешивания слоев (blending modes). (Языком фотошопа, по умолчанию который)
вы правы написал в спешке дурацкое название и аргументы и забыл исправить, после проверки.
inline QRgb normalBlend(const QRgb &back,const QRgb &front) - наверно так правильнее, правда в терминологии фотошопа.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Ноябрь 26, 2015, 11:55 »

так вычитающая модель это например CMYK для печати или рисование на бумаге.
Это модель прозрачности (а не цвета). Есть еще additive, ну и просто смешивание (цвета равноправны). И не фотошоп это придумал  Улыбающийся
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #8 : Ноябрь 27, 2015, 12:29 »

Это модель прозрачности (а не цвета). Есть еще additive, ну и просто смешивание (цвета равноправны). И не фотошоп это придумал  Улыбающийся
Ну придумано это было еще когда на прозрачной кальке рисовали и накладывали друг на друга.

Что значит вычитание, где почитать? У нас 2 цвета формата(RGB+A), алгоритм загоняет в прозрачность верхнего цвета нижний цвет - аналог кальки(полупрозрачность для краев).
p.s. добавил пару строк чтобы быстрее работало(как правило полупрозрачных символов мало)
Код:
    int aBack(qAlpha(back));
    if(!aBack)  return front;
    int aFront(qAlpha(front));
    if(!aFront) return back;
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Ноябрь 27, 2015, 14:12 »

Что значит вычитание, где почитать?
Не помню, так всю жизнь было Улыбающийся

Ну придумано это было еще когда на прозрачной кальке рисовали и накладывали друг на друга.
Другая модель (обычно называется "фильтр"): смотрим через зеленое (бутылочное) стекло. Зеленые лучи пропускает, остальные (частично) поглощает 
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #10 : Ноябрь 30, 2015, 11:39 »

Не помню, так всю жизнь было Улыбающийся
Я понял о чем вы говорите. У вас источник света за калькой(светящийся стол в темноте) и нарисованное на кальке поглощает свет. У меня ситуация другая - у меня источник света над калькой, непрозрачные пиксели видны сразу, а прозрачные и полупрозрачные отдаются следующему слою.
В кино так делали, нарисуют задний фон, а потом нарисуют микимауса на прозрачной бумаге(кальке) и накладывают сверху.

p.s. у меня значки с обводкой и бликами, сначала раскрашиваю в выбранный цвет маску, потом накладываю обводку и блики. Генерировать из векторных не стал, т.к. значки маленькие и получиться не очень красиво.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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