Qt:优化绘画事件

Posted

技术标签:

【中文标题】Qt:优化绘画事件【英文标题】:Qt: optimize the paint event 【发布时间】:2015-02-02 14:22:07 【问题描述】:

我目前正在从解码器读取图像并在小部件中绘制它的每一帧。 这就是我现在正在做的事情:

 paintEvent(...) 
    ...
    painter.setRenderHint(QPainter::Antialiasing, false);
    painter.setRenderHint(QPainter::HighQualityAntialiasing, false);
    QPixmap pmap = QPixmap::fromImage(glImage).scaledToWidth(width());
    painter.drawPixmap(0, (height() - pmap.height()) / 2, pmap);
    ... 
  

但是,我发现它的计算成本很高... 在 Qt 中不使用 OpenGL 有什么解决办法吗?

【问题讨论】:

【参考方案1】:

您可以尝试使用 QPainter::drawImage 而不是在图像表示(QImage -> QPixmap)之间进行手动转换。参考文档,它仍应提供缩放图像的方法-“注意:如果图像和矩形大小不一致,则图像将缩放以适合矩形。”。

【讨论】:

【参考方案2】:

首先,在绘画之前不需要缩放像素图。您可以将所需的宽度和高度作为参数传递给painter.drawPixmap。这将在绘画时缩放图像,这(可能)更快。

QPixmap pmap = QPixmap::fromImage(glImage);
int w = width();
// "scaledToWidth"
int h = w * pmap.height() / (double)pmap.width();
painter.drawPixmap(0, (height() - h) / 2, w, h, pmap);

然后,您可以尝试直接绘制图像。根据您使用的操作系统,这可能会更慢或更快。

例如,在 Windows 上,QPixmap 在内部由 QImage 表示。因此,QPixmap::fromImage 基本上会创建该图像的(可能不必要的)副本。

int w = width();
int h = w * glImage.height() / (double)glImage.width();
painter.drawImage(0, (height() - h) / 2, w, h, glImage);

如果您直接绘制图像,alpha 混合可能会变得非常昂贵。因此,如果可能,请使用没有 Alpha 通道或预乘 Alpha 的像素格式。 (在预乘格式中,红色、绿色和蓝色通道乘以 alpha 分量除以 255。)(另请参见:QImage::Format_ARGB32_Premultiplied is your friend)。

额外的事实:这基本上就是 Windows 上的 QPixmap::fromImage 所做的。如果您将带有 alpha 通道的 QImage 传递给该函数,则内部 QImage 将与预乘 alpha 一起存储以优化渲染性能。 See source code.

【讨论】:

以上是关于Qt:优化绘画事件的主要内容,如果未能解决你的问题,请参考以下文章

Qt 中聊天会话的最佳小部件

QT 信号槽 异步事件驱动 单线程 多并发

C#winform 通过Graphics绘画出来的画,怎么改透明度

qt paintEvent

[Qt]自定义表头实现过滤功能

使用ProcessOn绘画里程碑图