Как сделать QImage или QPixmap полупрозрачным или почему setAlphaChannel устарел? - PullRequest
7 голосов
/ 13 ноября 2010

4.7 и нравится накладывать два изображения на qgraphicsview. Изображение сверху должно быть полупрозрачным, чтобы было видно сквозь него. Первоначально оба изображения полностью непрозрачны. Я ожидал, что будет существовать некоторая функция для установки глобального альфа-значения для каждого пикселя, но, похоже, такой функции нет. Наиболее близким к нему является QPixmap :: setAlphaChannel (const QPixmap & alphaChannel), который, однако, помечен как устаревший с Qt-4.6. Вместо этого руководство ссылается на CompositionModes QPainter, но мне не удается добавить прозрачность непрозрачного изображения, как я хочу. Может ли кто-нибудь указать мне рабочий пример или поделиться кодом?

Edit: Я почти извиняюсь за собственный ответ, сейчас, через несколько часов после того, как задал вопрос. Из этой статьи я понял, что следующий код выполняет свою работу. Мне просто интересно, считается ли это «лучше» (что часто переводится как более быстрое), чем изменение значений альфа по пикселям.

QPainter p; 
p.begin(image);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.fillRect(image->rect(), QColor(0, 0, 0, 120));
p.end();            
mpGraphicsView->scene()->addPixmap(QPixmap::fromImage(image->mirrored(false,true),0));  

Ответы [ 3 ]

8 голосов
/ 01 апреля 2014

Используйте объект рисования и установите непрозрачность.

void ClassName::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setOpacity(1.00);  //0.00 = 0%, 1.00 = 100% opacity.
    painter.drawPixmap(QPixmap(path));
}
8 голосов
/ 13 ноября 2010

Демонстрационная композиция Qt может быть немного пугающей, потому что они пытаются все показать.Надеемся, что вам пригодится демоверсия плюс документация QPainter .Вы хотите использовать CompositionMode :: SourceOver и убедиться, что изображения конвертированы в ARGB32 (предварительно умноженное).Из документации:

When the paint device is a QImage, the image format must be set to Format_ARGB32Premultiplied or Format_ARGB32 for the composition modes to have any effect. For performance the premultiplied version is the preferred format.

2 голосов
/ 13 ноября 2010

Прежде всего, для внутренних операций с изображениями, вам часто нужно использовать QImage вместо QPixmap, так как функциональность прямого доступа к QPixmap ограничена.Причина в том, что QPixmaps хранятся на устройстве рендеринга, например, растровое изображение на X-сервере или текстура GL.С другой стороны, переход от QPixmap к QImage и обратно обходится дорого, поскольку часто приводит к копированию из памяти видеокарты в основную память и обратно.

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

for (int y = 0; y < image.height() ++y) {
  QRgb *row = (QRgb*)image.scanLine(y);
  for (int x = 0; x < image.width(); ++x) {
    ((unsigned char*)&row[x])[3] = alpha;
  }
}

Примечание: гораздо быстрее изменить каждый пиксель QImage, а затем выполнить painter.drawImage(), чем рисовать каждый пиксель с соответствующей альфа-версией.от руки.

...