I would like to draw icons (only one color) in different colors. To do so, I would like to import a single alpha-texture and then combine this with a given color in the application.
The result should be, that nothing is drawn on to the background, when the alpha-map has an opacity of 0 and the used color should be drawn, when the opacity is 1.
One soulution should be hidden somewhere in QPainter
, since you can manually set the Composition-Mode (QPainter::setCompositionMode
). But I don't get it to work like I want.
Does somebody have an idea?
Thanks in advance.
EDIT: Here is a little graphic explaining what I would like to do. I want to use a Alpha-Map like shown in the graphic and then use a color layer to create my icon. Important is, that the background stays transparent.
You can do thos using QPainter like this:
QColor color;
// set color value
// load gray-scale image (an alpha map)
QPixmap pixmap = QPixmap(":/images/earth.png");
// initialize painter to draw on a pixmap and set composition mode
QPainter painter(&pixmap);
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.setBrush(color);
painter.setPen(color);
painter.drawRect(pixmap.rect());
// Here is our new colored icon!
QIcon icon = QIcon(pixmap);
Here is gray-scale image and two colored icons which i get using the code above (QPixmap.save() method): icons
The DestinationIn
composition mode will do the trick.
Draw the color layer using the default composition mode of SourceOver
.
Draw the alpha layer using the DestinationIn
composition mode.
For example:
// https://github.com/KubaO/stackoverflown/tree/master/questions/alpha-mask-24943711
#include <QtWidgets>
QImage icon(int size) {
QImage image{size, size, QImage::Format_ARGB32_Premultiplied};
image.fill(Qt::transparent);
QPainter p(&image);
p.setRenderHint(QPainter::Antialiasing);
p.setPen(Qt::NoPen);
p.translate(image.rect().center());
p.scale(image.width()/2.2, image.height()/2.2);
p.setBrush(Qt::white);
p.drawEllipse(QRectF{-.5, -.5, 1., 1.});
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.setBrush(Qt::transparent);
p.drawEllipse(QRectF{-.3, -.3, .6, .6});
for (auto angle : {0., 100., 150.}) {
p.save();
p.rotate(angle);
p.drawRect(QRectF{-.1, 0, .2, -1.});
p.restore();
}
return image;
}
QImage checkers(int size) {
QImage img{size*2, size*2, QImage::Format_ARGB32_Premultiplied};
QPainter p(&img);
p.fillRect(0, 0, size, size, Qt::darkGray);
p.fillRect(size, size, size, 2*size, Qt::darkGray);
p.fillRect(size, 0, size, size, Qt::lightGray);
p.fillRect(0, size, size, size, Qt::lightGray);
return img;
}
void drawColorIcon(QPainter & p, QColor color, const QImage & alpha)
{
p.save();
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.fillRect(QRect{0, 0, alpha.width(), alpha.height()}, color);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
p.drawImage(0, 0, alpha);
p.restore();
}
QImage drawColorIconProof(QColor color, const QImage & alpha) {
QImage result{alpha.size(), alpha.format()};
QPainter p(&result);
drawColorIcon(p, color, alpha);
p.setCompositionMode(QPainter::CompositionMode_DestinationAtop);
p.fillRect(alpha.rect(), {checkers(10)});
return result;
}
int main(int argc, char *argv[])
{
QApplication app{argc, argv};
QLabel label;
label.setPixmap(QPixmap::fromImage(drawColorIconProof("orangered", icon(200))));
label.show();
return app.exec();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With