在Qt5中为qwebview创建色度键

时间:2015-03-19 19:36:58

标签: qt qwebview qpainter chromakey

我正在尝试在Qt5中为qwebview创建一个色度键。这意味着我需要使特定颜色变得透明(其他小部件应该通过webview的具有该颜色的像素可见)。我发现它可以使用QPainter :: CompositionMode操作完成,但不能使它工作。

例如,我需要使webview的所有黑色像素都透明(源颜色应在运行时更改)。

我在我的课程中重新实现了QWebView :: paintEvent(从Qt源代码中获取代码的一部分),但不知道下一步该做什么

WebView::paintEvent(QPaintEvent *event) {
    if (!page()) return;
    QWebFrame *frame = page()->mainFrame();
    QPainter painter(this);
    painter.setRenderHints(renderHints());
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    frame->render(&painter, event->region());

}

我找到了一种方法,如何使用以下代码使任何源颜色变为白色:

QWebFrame *frame = page()->mainFrame();
QImage source_image(size(), QImage::Format_ARGB32_Premultiplied);
QImage result_image(size(), QImage::Format_ARGB32_Premultiplied);

QPainter imagePainter(&source_image);
imagePainter.setRenderHints(renderHints());
frame->render(&imagePainter, event->region());
imagePainter.end();

QImage mask = source_image.createMaskFromColor(qRgb(0x00,0x00,0x00)); // Source color

QPainter resultPainter(&result_image);
resultPainter.drawImage(source_image.rect(), source_image);
resultPainter.setCompositionMode(QPainter::CompositionMode_Screen);
resultPainter.drawImage(source_image.rect(), mask);

QPainter painter(this);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
painter.drawImage(0, 0, result_image);

但我不知道如何将白色转换为透明色。

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,但它消耗了大量的CPU。

首先需要设置

setStyleSheet("QWebView { background: transparent }");
setAttribute(Qt::WA_OpaquePaintEvent, true);

WebView的构造函数中的某个地方(我只是忘了在第一条消息中提到它)。然后重新实现paintEvent:

void WebView::paintEvent(QPaintEvent *event)
{
    if (!page())
        return;

    QWebFrame *frame = page()->mainFrame();
    QPainter painter(this);
    QColor chroma_color(0, 0, 0); // A color that should be transparent
    float opacity_level = 0.9; // WebView opacity

    m_render_pixmap.fill(Qt::transparent);

    QPainter pixmapPainter(&m_render_pixmap);
    pixmapPainter.setRenderHints(renderHints());
    frame->render(&pixmapPainter, event->region());
    pixmapPainter.end();
    m_render_pixmap.setMask(m_render_pixmap.createMaskFromColor(
        chroma_color, Qt::MaskInColor));

    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.setOpacity(opacity_level);
    painter.drawPixmap(QPoint(event->rect().left(), event->rect().top()), m_render_pixmap, event->rect());
    painter.end();
}

m_render_pixmap是QPixmap的一个实例。每次调用paintEvent时我都不想重新创建它。我只是在resizeEvent

上重新创建它
void WebView::resizeEvent(QResizeEvent *event)
{
    QWebView::resizeEvent(event);
    m_render_pixmap = QPixmap(size());
}

上面的代码工作得很好,但在我的情况下,我想在webview下面渲染一个视频小部件。所以WebView :: paintEvent每秒调用大约25次,每次调用在我的PC上以窗口模式大约需要20-25毫秒。在全屏模式下,它占用了一个CPU内核的大约100%。