Paul February 2016

Make polygonal hole in QImage alpha channel

I'm trying to make polygonal hole in QImage alpha channel. My current implementation use deprecated 'alphaChannel' method and works slow (because it use containPoint for every image pixel instead of draw polygon).

QImage makeImageWithHole(const QImage & image, const std::vector<QPoint> & hole_points)
{
  QImage newImage = image.convertToFormat(QImage::Format_ARGB32);

  QImage alpha = newImage.alphaChannel();
  QPolygon hole(QVector<QPoint>::fromStdVector(hole_points));
  for (int x = 0; x < image.width(); x++)
  {
    for (int y = 0; y < image.height(); y++)
    {
      if (hole.containsPoint(QPoint(x, y), Qt::OddEvenFill))
      {
        alpha.setPixel(x, y, 0);
      }
    }
  }
  newImage.setAlphaChannel(alpha);

  return newImage;
}

I was also trying to implement it using painter and proper composition mode, but in result I have white artifacts on polygon borders.

QImage makeImageWithHole(const QImage & image, const std::vector<QPoint> & hole)
{
  QImage newImage = image.convertToFormat(QImage::Format_ARGB32);

  QPainter p(&newImage);
  p.setCompositionMode(QPainter::CompositionMode_SourceOut);
  p.setPen(QColor(255, 255, 255, 255));
  p.setBrush(QBrush(QColor(255, 255, 255, 255)));
  p.drawPolygon(hole.data(), hole.size());
  p.end();

  return newImage;
}

What is proper way to do this?

Answers


Evgeny February 2016

I think you should enable antialiazing like this:

QPainter p(&newImage);
p.setRenderHints(QPainter::Antialiasing);

Post Status

Asked in February 2016
Viewed 1,255 times
Voted 6
Answered 1 times

Search




Leave an answer