开发者

Phonon's VideoWidget show wrong colors on a QGLWidget (Qt, Python)

开发者 https://www.devze.com 2023-04-11 16:39 出处:网络
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,

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.

Phonon's VideoWidget show wrong colors on a QGLWidget (Qt, Python)

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/resource开发者_高级运维s/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_())


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号