Phonon 的 VideoWidget 在 QGLWidget(Qt、Python)上显示错误的颜色
我有一个宠物项目,其中包含一个具有显示字幕功能的视频播放器。 到目前为止,我一直在处理项目的其他部分,但现在我必须以最好的方式实现字幕渲染部分。
除了这个。
但是当我使用这段代码时,我得到了错误的视频图片。
颜色已修改:红色→蓝色,蓝色→红色等。
有人可以帮我吗这段代码,或者向我展示另一种在视频顶部渲染字幕的解决方案?
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.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 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.
一些操作系统、框架、文件格式等将颜色存储为 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.