问题描述
我正在为 Ubuntu Touch 开发一个应用程序,它应该能够读取 QR 码。它依赖于自定义视频过滤器子类,但是我无法从 QVideoFrame
实例中提取单个图像。 QVideoFrame::map
将失败。我的研究表明,我必须使用 OpenGL 句柄来读取 2D 纹理,而不是直接访问,类似于这些情况:
- https://github.com/stephenquan/MyVideoFilterApp/blob/master/QVideoFrameToQImage.cpp
- QVideoFrame::map() crashes
- https://forum.qt.io/topic/103430/qvideoframe-map-is-false-in-android
- https://lists.qt-project.org/pipermail/interest/2018-June/030295.html
所以我正在尝试使用 OpenGL 函数实现 QVideoFrame::map
替换。
然而,虽然从上面的例子中方法似乎很清楚,但我似乎无法从 QImage
中获得有效的 QVideoFrame
。我有很多不确定性;我从未使用过 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,frame.width(),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
输入视频流似乎是 QVideFrame::Format_RGB32
格式,至少 frame.pixelFormat()
报告是这样。
这是否重要,或者 GL_RGBA
无论如何都可以工作,我只需要确保 img
的格式正确,因此内部缓冲区足够大?因此,QImage::Format_RGBA8888
是否正确?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)