Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt drawing icons using color and alpha-map

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.

enter image description here

like image 371
ruhig brauner Avatar asked Jul 24 '14 20:07

ruhig brauner


2 Answers

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

like image 67
Arkady Dyakonov Avatar answered Nov 03 '22 02:11

Arkady Dyakonov


The DestinationIn composition mode will do the trick.

  1. Draw the color layer using the default composition mode of SourceOver.

  2. Draw the alpha layer using the DestinationIn composition mode.

For example:

screenshot

// 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();
}
like image 2
Kuba hasn't forgotten Monica Avatar answered Nov 03 '22 02:11

Kuba hasn't forgotten Monica