PyQt6中如何利用sip.voidptr向QVideoFrame写入像素数据
在PyQt6中给QVideoFrame填充像素数据的解决方案
针对PyQt6中QVideoFrame.bits()返回sip.voidptr无法直接赋值bytes的问题,这里提供两种简便的解决方法:
方法一:利用numpy操作内存
numpy可以直接映射sip.voidptr指向的内存,并且支持直接从bytes转换数据:
from PyQt6 import QtCore, QtMultimedia import numpy as np pfmt = QtMultimedia.QVideoFrameFormat.PixelFormat.Format_Y8 ffmt = QtMultimedia.QVideoFrameFormat(QtCore.QSize(1280, 1024), pfmt) vf = QtMultimedia.QVideoFrame(ffmt) vf.map(QtMultimedia.QVideoFrame.MapMode.ReadWrite) # 计算总字节数 size = vf.bytesPerLine(0) * vf.height() # 将voidptr映射为numpy uint8数组(无内存拷贝) np_frame = np.ndarray(shape=(size,), dtype=np.uint8, buffer=vf.bits(0)) # 准备像素数据并赋值 data_bytes = bytes(255 for _ in range(size)) np_frame[:] = np.frombuffer(data_bytes, dtype=np.uint8) vf.unmap()
方法二:构造同类型的sip.array赋值
直接将bytes转换为与目标数组同类型的sip.array,再进行切片赋值:
from PyQt6 import QtCore, QtMultimedia import sip pfmt = QtMultimedia.QVideoFrameFormat.PixelFormat.Format_Y8 ffmt = QtMultimedia.QVideoFrameFormat(QtCore.QSize(1280, 1024), pfmt) vf = QtMultimedia.QVideoFrame(ffmt) vf.map(QtMultimedia.QVideoFrame.MapMode.ReadWrite) # 计算总字节数 size = vf.bytesPerLine(0) * vf.height() # 获取视频帧的内存数组 dest_arr = vf.bits(0).asarray(size) # 构造unsigned char类型的sip.array('B'对应unsigned char) src_arr = sip.array('B', bytes(255 for _ in range(size))) # 批量赋值 dest_arr[:] = src_arr vf.unmap()
错误原因说明
之前直接给sip.array赋值bytes报错,是因为sip.array(unsigned char)只能接受同类型的数组作为赋值对象,无法直接识别Python原生的bytes类型,必须先转换为匹配的数组类型。
内容的提问来源于stack exchange,提问作者JS S
相关产品推荐
相关产品推荐

