Уменьшение альфа QPixmap / QImage с минимальной гарантированной альфа

Я хочу реализовать метод, который уменьшает альфа каждого пикселя в QPixmap (4.8) на 1, каждый раз, когда он вызывается. Между вызовами могут быть добавлены новые линии к изображению (с альфа 255). Кроме того, я хотел бы иметь более низкий порог альфа, скажем, 15. Пиксели, у которых начальная альфа равна 0, сохранят эту альфа. В псевдокоде:

if alpha == 0:
newAlpha = 0
else:
newAlpha = max(15, alpha - 1)

Прямо сейчас я имею в виду два метода. Первый — это преобразование в QImage и попиксельное уменьшение альфа. Однако у этого есть два недостатка: производительность и цветовые артефакты: цвета некоторых пикселей сильно изменяются. Артефакты появляются, когда QPainting результирующего qpixmap на другой qpixmap, заполненный одним цветом (с QPainter::CompositionMode_SourceOver). Это, скорее всего, связано с дизерингом ?! Я попробовал два доступных, оба производят артефакты этих типов.

QImage image = pixmap.toImage();
for (int y = 0; y < image.height(); ++y) {
for (int x = 0; x < image.width(); ++x) {
QRgb col = image.pixel(x,y);
int alpha = qAlpha(col);

if(alpha>15) {
alpha -= 1;
QRgb newCol = qRgba(qRed(col), qGreen(col), qBlue(col), alpha);
image.setPixel(x,y, newCol);
}
}
}
pixmap = QPixmap::fromImage(image, Qt::DiffuseAlphaDither | Qt::NoOpaqueDetection);

Артефакты появляются с этим:

QPixmap screen;
...
screen.fill(Qt::transparent);
QPainter painter( &screen );
// remove anti-aliasing, which (with current composition mode) results in even stronger artefacts
painter.setRenderHints(0);
background.fill(someRandomColor);

painter.drawPixmap(0, 0, w, h, background);
painter.drawPixmap(0, 0, w, h, pixmap);
painter.end();

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

Итак, сейчас есть три вопроса:

Можно ли избежать цветовых артефактов с помощью обхода QImage?

Или можно сопоставить приведенный выше псевдокод с чистыми операциями QPixmap / QPainter?

Есть ли совершенно другая идея?

РЕДАКТИРОВАТЬ:

QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);

Похоже, удалить артефакты. Прежде чем это было бы преобразовано в QImage::Format_ARGB32_Premultiplied и, следовательно, артефакты. Но теперь он еще менее производительный

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]