Phonon 的 VideoWidget 在 QGLWidget(Qt、Python)上显示错误的颜色

发布于 2024-12-08 10:44:40 字数 3075 浏览 0 评论 0原文

我有一个宠物项目,其中包含一个具有显示字幕功能的视频播放器。 到目前为止,我一直在处理项目的其他部分,但现在我必须以最好的方式实现字幕渲染部分。

除了这个。

但是当我使用这段代码时,我得到了错误的视频图片。 红色和蓝色交换的视频帧

颜色已修改:红色→蓝色,蓝色→红色等。

有人可以帮我吗这段代码,或者向我展示另一种在视频顶部渲染字幕的解决方案?

PS:我使用 PySide 1.0.0、1.0.6 以及 Arch 和 Ubuntu linux 对其进行了测试。


编辑:解决方法

借助 alexisdm,可以使用丑陋的 hack。它更改了 paint() 方法来反转颜色。

import sys
from PySide.QtGui import QApplication, QMessageBox
# overlay
from PySide.QtGui import QGraphicsScene, QGraphicsView, QGraphicsProxyWidget, QPainter, QImage
from PySide.QtOpenGL import QGLWidget

from PySide.phonon import Phonon

try:
    from OpenGL import GL
except ImportError:
    app = QApplication(sys.argv)
    QMessageBox.critical(None, "OpenGL 2dpainting",
                            "PyOpenGL must be installed to run this example.",
                            QMessageBox.Ok | QMessageBox.Default,
                            QMessageBox.NoButton)
    sys.exit(1)


#class CustomProxy(QGraphicsProxyWidget):
#    def __init__(self, parent=None):
#        QGraphicsProxyWidget.__init__(self, parent)
#
#
#    def boundingRect(self):
#        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 0, 0);


class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None):
        QGraphicsProxyWidget.__init__(self, parent)


    def boundingRect(self):
        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 0, 0);

# This is the magic:
    def paint(self, painter, option, widget=None):
        painter_inverted = QPainter()
        brect= QGraphicsProxyWidget.boundingRect(self)
        invertedColor = QImage(brect.width(),brect.height(),QImage.Format_RGB32)
        painter_inverted.begin(invertedColor)
        QGraphicsProxyWidget.paint(self,painter_inverted, option, widget)
        painter_inverted.end()
        painter.drawImage(0,0,invertedColor.rgbSwapped())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setApplicationName("tete")

    scene = QGraphicsScene()

    media = Phonon.MediaObject()
    video = Phonon.VideoWidget()
    Phonon.createPath(media, video)

    proxy = CustomProxy()
    proxy.setWidget(video)
    rect = proxy.boundingRect()
    #proxy.setPos(0, 0)
    #proxy.show()
    scene.addItem(proxy)

    media.setCurrentSource("/home/boo/Development/mindmap/test/resources/glvideo.avi")
    media.play()

    titem = scene.addText("Bla-bla-bla")
    titem.setPos(130, 130)
    #titem.setPos(rect.width()/2, rect.height()/2)

    view = QGraphicsView(scene)
    vp = QGLWidget()
    view.setViewport(vp)

    #view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
    view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
    view.setWindowTitle("Eternal fire")

    view.show()
    sys.exit(app.exec_())

I have a pet project that contains a videoplayer with a feature to display subtitles.
Until now I was working on the other parts of my project, but now I have to implement the subtitle rendering part, in the best way.

I didn't find anything useful towards that end, except this.

But when I use this code I get a wrong picture of the video.
video frame with red and blue swapped

Colors are modified: red → blue, blue → red, etc.

Can someone help me with this code, or show me another solution to render subtitles on top of a video?

PS: I tested it with PySide 1.0.0, 1.0.6 and on Arch and Ubuntu linux.


Edit: Workaround

An ugly hack is available, thanks to alexisdm. It changes the paint() method to invert the colors.

import sys
from PySide.QtGui import QApplication, QMessageBox
# overlay
from PySide.QtGui import QGraphicsScene, QGraphicsView, QGraphicsProxyWidget, QPainter, QImage
from PySide.QtOpenGL import QGLWidget

from PySide.phonon import Phonon

try:
    from OpenGL import GL
except ImportError:
    app = QApplication(sys.argv)
    QMessageBox.critical(None, "OpenGL 2dpainting",
                            "PyOpenGL must be installed to run this example.",
                            QMessageBox.Ok | QMessageBox.Default,
                            QMessageBox.NoButton)
    sys.exit(1)


#class CustomProxy(QGraphicsProxyWidget):
#    def __init__(self, parent=None):
#        QGraphicsProxyWidget.__init__(self, parent)
#
#
#    def boundingRect(self):
#        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 0, 0);


class CustomProxy(QGraphicsProxyWidget):
    def __init__(self, parent=None):
        QGraphicsProxyWidget.__init__(self, parent)


    def boundingRect(self):
        return QGraphicsProxyWidget.boundingRect(self).adjusted(0, 0, 0, 0);

# This is the magic:
    def paint(self, painter, option, widget=None):
        painter_inverted = QPainter()
        brect= QGraphicsProxyWidget.boundingRect(self)
        invertedColor = QImage(brect.width(),brect.height(),QImage.Format_RGB32)
        painter_inverted.begin(invertedColor)
        QGraphicsProxyWidget.paint(self,painter_inverted, option, widget)
        painter_inverted.end()
        painter.drawImage(0,0,invertedColor.rgbSwapped())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setApplicationName("tete")

    scene = QGraphicsScene()

    media = Phonon.MediaObject()
    video = Phonon.VideoWidget()
    Phonon.createPath(media, video)

    proxy = CustomProxy()
    proxy.setWidget(video)
    rect = proxy.boundingRect()
    #proxy.setPos(0, 0)
    #proxy.show()
    scene.addItem(proxy)

    media.setCurrentSource("/home/boo/Development/mindmap/test/resources/glvideo.avi")
    media.play()

    titem = scene.addText("Bla-bla-bla")
    titem.setPos(130, 130)
    #titem.setPos(rect.width()/2, rect.height()/2)

    view = QGraphicsView(scene)
    vp = QGLWidget()
    view.setViewport(vp)

    #view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
    view.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
    view.setWindowTitle("Eternal fire")

    view.show()
    sys.exit(app.exec_())

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁月静好 2024-12-15 10:44:40

正如 alexisdm 在评论中指出的,这是 Qt 的一个已知错误。

它可以在 #GTBUG-8738 中找到,有人甚至添加了解决方法。

As pointed out by alexisdm in a comment this is a known bug of Qt.

It can be found as #GTBUG-8738 where someone even added a workaround.

时间你老了 2024-12-15 10:44:40

一些操作系统、框架、文件格式等将颜色存储为 RGB,一些存储为 BGR(后者在 Windows 中更常见)。因此,如果将颜色从其中一种传递到另一种,则红/蓝交换很常见。仔细检查您的颜色结构,以确保您使用的颜色结构适合您所使用的技术。

Some OS, frameworks, file formats, etc. store color as RGB, some as BGR (the latter is more common in Windows). So Red/Blue swapping is common if you pass colors from one of these to the other. Look at your color structures closely to make sure you are using the right ones for the technologies you are using.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文