除了上述方法之外,还有其他一些办法可以缩放视频,具体如下:
- 使用
QGraphicsView
控件
将视频控件嵌入到 QGraphicsView
中,并使用 QGraphicsView
的缩放功能来实现画面缩放。
// 创建 QGraphicsScene 和 QGraphicsView 对象
m_pScene = new QGraphicsScene;
m_pView = new QGraphicsView(m_pScene, this);
// 将视频控件添加到场景中
m_pItem = m_pScene->addWidget(m_pVideoWidget);
m_pItem->setFlag(QGraphicsItem::ItemIsSelectable, false);
m_pItem->setFlag(QGraphicsItem::ItemIsMovable, false);
// 设置视图的大小策略和可调整大小性质
m_pView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_pView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_pView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_pView->setResizeAnchor(QGraphicsView::NoAnchor);
m_pView->setInteractive(true);
// 缩放视图
float scaleFactor = 0.5; // 缩放比例
QMatrix matrix;
matrix.scale(scaleFactor, scaleFactor);
m_pView->setMatrix(matrix);
- 使用
OpenGL
渲染
通过 OpenGL 来实现画面的渲染和缩放。这种方法需要使用 Qt 提供的 QOpenGLWidget
控件,并在其内部使用 OpenGL 进行渲染。
void VideoWidget::initializeGL()
{
// 初始化 OpenGL 环境
initializeOpenGLFunctions();
// 设置 OpenGL 状态
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void VideoWidget::paintGL()
{
// 清除屏幕
glClear(GL_COLOR_BUFFER_BIT);
// 绘制视频帧
if (m_pPlayer->state() == QMediaPlayer::PlayingState && m_pPlayer->isVideoAvailable()) {
m_texture.bind();
m_shaderProgram.setUniformValue("texture", 0);
m_shaderProgram.setAttributeArray("vertex", GL_FLOAT, m_vertices.constData(), 2);
m_shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
m_texture.release();
}
}
void VideoWidget::resizeGL(int w, int h)
{
// 调整视口大小
glViewport(0, 0, w, h);
}
void VideoWidget::createShaderProgram()
{
// 创建着色器程序
QFile vertexShaderFile(":/shaders/vertex.glsl");
QFile fragmentShaderFile(":/shaders/fragment.glsl");
if (!vertexShaderFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open vertex shader file";
return;
}
if (!fragmentShaderFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open fragment shader file";
return;
}
QByteArray vertexShaderSource = vertexShaderFile.readAll();
QByteArray fragmentShaderSource = fragmentShaderFile.readAll();
const char* vsrc = vertexShaderSource.constData();
const char* fsrc = fragmentShaderSource.constData();
m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc);
m_shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc);
if (!m_shaderProgram.link()) {
qWarning() << "Failed to link shader program";
return;
}
}
void VideoWidget::createTexture()
{
// 创建纹理对象
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
m_pPlayer->videoSurface()->surfaceFormat().frameWidth(),
m_pPlayer->videoSurface()->surfaceFormat().frameHeight(),
0,
GL_BGRA,
GL_UNSIGNED_BYTE,
nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
m_texture.setData(QOpenGLTexture::BGRA, QOpenGLTexture::UInt8, m_pPlayer->videoSurface()->surfaceFormat().frameWidth(), m_pPlayer->videoSurface()->surfaceFormat().frameHeight(), 0, nullptr);
}
这种方法需要对 OpenGL 有一定的了解和掌握,但可以实现更高效的视频渲染和缩放。