Почему использование предварительно умноженной альфа не имеет "значительно худшей производительности"?
QPainter
отвечает за рисование и композитинг в Qt. В документации есть раздел, в котором говорится о производительности. Мой вопрос касается предложения, выделенного жирным шрифтом из следующего абзаца.
Растр - этот бэкэнд реализует весь рендеринг в чистом программном обеспечении и всегда используется для рендеринга в QImages. Для оптимальной производительности используйте только типы форматов QImage::Format_ARGB32_Premultiplied, QImage::Format_RGB32 или QImage::Format_RGB16. Любой другой формат, включая QImage::Format_ARGB32, имеет значительно худшую производительность. Этот движок по умолчанию используется для QWidget и QPixmap.
Я понимаю, что умножение цветовых каналов на альфа - это то, что делается в операции "источник поверх". Это умножение может быть выполнено заранее, чтобы избежать этого в композиторе. Выполнение этого умножения включает в себя умножение каналов RGB на альфу, а затем деление на 255 (или умножение на некоторое магическое число, которое переполняется правильным образом для имитации деления). Это шесть целочисленных умножений на пиксель. Разумеется, выполнение дополнительных шести целочисленных умножений не имеет "значительно худшей производительности"?
Умножение альфы действительно так медленно? Возможно, они просто заявляют, что не пытаются оптимизировать этот путь кода так сильно, как другой, поэтому нет никаких гарантий относительно того, как он работает?
2 ответа
Пожалуйста, ознакомьтесь с подробным объяснением здесь: https://pspdfkit.com/blog/2016/a-curious-case-of-android-alpha/ Конечно, это не относится к директиве Qt, но к случаю, почему Предварительно умноженные растровые изображения имеют смысл.
Это имеет некоторый смысл в вашем случае, так как я предполагаю, что какой-то виджет рисует изображение, и предполагается, что он может нарисовать его несколько раз. В любом случае, виджет во время рисования будет предварительно умножать альфа. Таким образом, вы могли бы также быть очень откровенными об этом - в конце концов, преобразования формата изображения являются однострочными, так что это не так, как если бы вы должны были написать страницу кода, чтобы справиться с этим. Так:
class MyViewer : public QWidget {
Q_OBJECT
QImage m_image;
public:
Q_SLOT void setImage(const QImage &image) {
m_image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
update();
}
...
};