首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ffpyplayer图像到QPixmap

ffpyplayer图像到QPixmap
EN

Stack Overflow用户
提问于 2019-10-25 21:19:21
回答 1查看 676关注 0票数 0

我正在寻找一种使用QPixmap将视频文件流到PyQt中的FfPyPlayer的方法。文档给出了一个将图像对象流出播放机的示例,但是我不知道如何将此图像转换为QPixmap。我确实看到了一种将其转换为字节数组的方法,QPixmap确实有一个QPixmap.loadFromData()函数,但我无法成功地将这两者结合在一起。

下面是文档中的示例:

代码语言:javascript
复制
from ffpyplayer.player import MediaPlayer
import time

player = MediaPlayer(filename)
val = ''
while val != 'eof':
    frame, val = player.get_frame()
    if val != 'eof' and frame is not None:
        img, t = frame
        # Now what?!

编辑好了,我想出了一个解决方案,将FfPyPlayer图像转换为PIL,然后通过枕头ImageQt.toqpixmap()方法将QPixmap转换成PIL。然而,我不愿将此作为一个答案,因为这似乎效率低下,我想知道是否还有其他人有更好的解决办法。

代码语言:javascript
复制
from ffpyplayer.player import MediaPlayer
from PIL import ImageQt, Image

player = MediaPlayer(filename)
val = ''
while val != 'eof':
    frame, val = player.get_frame()
    if val != 'eof' and frame is not None:
        img, t = frame

        data = img.to_bytearray()[0]
        img2 = Image.frombytes("RGB", img.get_size(), bytes(data))

        pixmap = ImageQt.toqpixmap(img2) # <- returns a QPixmap
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-29 09:51:43

问题是,QPixmap.loadFromData()需要实际的图像“文件”,而ffpyplayer (如ffmpeg)提供的实际上是原始图像,即图像的实际表示(栅格化),因为它们最终会出现。

由于各种原因,QPixmap不能直接处理原始数据,因为它的目的是在屏幕上显示图像,而QImages可以,因为它们也是独立于硬件的。

QImage可以加载原始图像数据(例如,如果图像被压缩,则原始数据是未压缩图像的实际表示形式),但它需要了解一些关于“图像格式”的信息,以及图像的宽度/高度。

当您使用QPixmap.loadFromData()时,实际发生的是Qt“猜测”图像文件格式,解压缩它以获取关于“每个像素”的数据,获取图形大小和像素格式,然后构建一个包含所有这些信息的内部QImage,并最终将其返回为QPixmap。

在本例中,您已经拥有了ffpyplayer提供的所有数据,所以只需跳过第一个“解码”段落,创建一个QImage,然后从其中获得一个QPixmap。

代码语言:javascript
复制
while val != 'eof':
    frame, val = player.get_frame()
    if val != 'eof' and frame is not None:
        img, t = frame

        data = img.to_bytearray()[0]
        width, height = img.get_size()

        # the technical name for the 'rgb24' default pixel format is RGB888,
        # which is QImage.Format_RGB888 in the QImage format enum
        qimage = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB888)
        pixmap = QtGui.QPixmap.fromImage(qimage)

注意,默认的out_fmt of MediaPlayer是‘rgb24 24’,我怀疑您是否需要更改它,但是如果您确实避免了任何基于YUV的像素格式,因为QImage不支持它们。它仍然可以转换(有几种方法),但我不建议这样做。

最后,考虑高宽比,这可能会改变源图像和实际表示(例如,变形格式)之间的变化。您可以从player.get_metadata()获得这一点,如果它不匹配图像的高宽比,您可以使用以下方法获得正确的图像:

代码语言:javascript
复制
pixmap = pixmap.scaled(targetWidth, targetHeight, 
    QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58565864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档