1

我正在为 Ubuntu Touch 开发一个应用程序,它应该能够读取 QR 码。它依赖于自定义视频过滤器子类,但是我无法从QVideoFrame实例中提取单个图像。将QVideoFrame::map失败。我的研究表明,我必须使用 OpenGL 句柄来读取 2D 纹理,而不是直接访问,类似于以下情况:

所以我正在尝试QVideoFrame::map使用 OpenGL 函数来实现替换。

但是,尽管从上述示例中可以清楚地看出该方法,但我似乎无法QImageQVideoFrame. 我有许多不确定性;我从未使用过 OpenGL,而且我对图像格式也不太熟悉。事实上,我并没有在自己的实现上工作,而是试图让qzxing库在我的应用程序中工作。我已经在 SailfishOS 下工作了(QVideoFrame::map刚刚工作),我正在将我的应用程序移植到 Ubuntu Touch。

目前我有这个:

QImage img(frame.width(), frame.height(), QImage::Format_RGBA8888);

GLuint textureId = frame.handle().toUInt();
QOpenGLContext *ctx = QOpenGLContext::currentContext();
QOpenGLFunctions *f = ctx->functions();
GLuint fbo;
f->glGenFramebuffers(1, &fbo);
GLuint prevFbo;
f->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo);
f->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
f->glReadPixels(0, 0, frame.width(), frame.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.bits());

const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test.png";
qDebug() << "Saving image  at:" << path << img.save(path) << " size: " << img.size() << "/" << img.sizeInBytes();

当我尝试将图像保存到磁盘时(为了检查它的外观,如果它甚至包含任何东西),QImage::save将返回false并打印:

Saving image at: "/home/phablet/Pictures/qrtest/test.png" false  size:  QSize(1920, 1088) / 8355840

输入视频流似乎是 format QVideFrame::Format_RGB32,至少这是 frame.pixelFormat()报告的内容。这是否重要,或者GL_RGBA无论如何都会起作用,我只需要确保img格式正确,所以内部缓冲区足够大吗?因此会是QImage::Format_RGBA8888正确的吗?

为什么生成的图像看起来无效?我怎样才能解决这个问题?

4

0 回答 0