使用 QT 查看来自相机的流式图像
Posted
技术标签:
【中文标题】使用 QT 查看来自相机的流式图像【英文标题】:Using QT to view streaming images from camera 【发布时间】:2011-06-28 00:41:10 【问题描述】:我有一个软件可以通过网络将 JPG 发送到应该显示这些图像的 GUI 客户端。我基本上想将它们显示到 qt 窗口,但我遇到了 qt 如何显示连续 JPG 的问题。我做了一个测试,看看我是否通过将图像打印到文件中正确获取图像,并且检查正常。主要代码如下:
int main(int argc, char *argv[])
// initialize resources, if needed
// Q_INIT_RESOURCE(resfile);
QApplication app(argc, argv);
CameraWindow cw;
cw.show();
//app.setActiveWindow(&cw);
cw.getData(); // this paints the window
return app.exec();
这是初始化小部件的代码:
class CameraWindow : public QDialog
Q_OBJECT
public:
bool serverConnected;
void getData();
CameraWindow()
imgl = new QLabel;
widget.scrollImage->setWidget(imgl);
widget.scrollImage->setBackgroundRole(QPalette::Dark);
QLabel *imgl;
virtual ~CameraWindow();
private:
Ui::CameraWindow widget;
;
这是应该将图像绘制到无限循环内的屏幕的代码的相关部分:
getData() 从 main 调用:
while (myrval < Header.imageSize)
myrval = myrval + recv(msgsock, (char*) ((int) buff + myrval),
Header.imageSize- myrval, 0);
//buff contains the jpg at this point
QPixmap imgjpg;
imgjpg.loadFromData((const unsigned char*)buff, Header.imageSize, "JPG");
//scroll image is the parent that displays child
//in this case, the label
imgl->setPixmap(imgjpg);
我让它只适用于从文件加载的一个图像,但是当我对一组流图像使用相同的方法时,这不起作用。我是 Qt 新手,所以我确定我有一个微妙的错误。
非常感谢!
【问题讨论】:
您如何循环调用recv()
并加载图像? (你能把这两个任务分成各自的功能吗?)
【参考方案1】:
因为您处于无限循环中,Qt 可能没有机会处理事件。你可以在 setPixmap 之后尝试调用 QCoreApplication::processEvents 吗?
【讨论】:
啊有趣!这似乎是问题所在。我会尽快尝试这个。谢谢!【参考方案2】:我建议创建一个 ImageProvider
类来提醒其他人它已准备好图像:
public class ImageProvider : QObject
Q_OBJECT
public:
QPixmap getCurrentImage() const /* retrieve current image */
signals:
void newImageAvailable();
;
现在您需要一个类来显示它,所以我们称它为 ImageDisplayer
并假设它有一个名为 imageLabel
的标签,上面设置了您当前的图像:
public class ImageDisplayer : QWidget
Q_OBJECT
QLabel *imageLabel;
ImageProvider *provider;
public:
ImageDisplayer(QWidget *parent, ImageProvider *imageProvider)
this->imageLabel = /* setup QPixmap */;
this->imageProvider = imageProvider;
connect(imageProvider, SIGNAL("newImageAvailable()"), SLOT("setNewImage()"));
public void setNewImage()
imageLabel->setPixmap(imageProvider->getCurrentImage());
update(); // schedule the repaint
;
只要 Qt 认为合理,对update 的调用将导致重绘发生。这也允许跳帧和其他事情(您可能不想要)。
最后,您需要确保所有内容都通过您的主小部件连接起来:
public class MainWidget : QMainWindow
Q_OBJECT
ImageDisplayer *imageDisplayer;
ImageProvider *imageProvider;
public:
void MainWidget()
this->imageProvider = new ImageProvider(/*your dependencies*/);
this->imageDisplayer = new ImageDisplayer(this, imageProvider);
主要是:
int main(int argc, char* argv[])
QApplication app(argc, argv);
MainWidget w;
w.show();
return app.exec();
这可能不是性能最好的实现,但它很简单并且可以满足您的需求。
【讨论】:
我喜欢你的设置,但我仍然很困惑我的主代码会是什么样子?它看起来像这样吗: ImageProvider ip; ImageDisplayer id(&cw, &ip);您有完整示例的链接吗?我无法查看控制流【参考方案3】:除了 Mason Chang 的回答之外 - 一个更好的方法是让显示器成为一个插槽,然后从计时器调用该插槽。
setTimer 值为 0 实际上是一个循环 - 它会在槽完成后立即调用,但仍允许其他处理。
【讨论】:
以上是关于使用 QT 查看来自相机的流式图像的主要内容,如果未能解决你的问题,请参考以下文章
使用 OpenGL 在 Qt 中显示来自 DirectShow 的原始图像数据
如何使用 Qt/C++ 小部件(不是 QML)从 Android 相机获取图像
如何从 iOS 设备(而不是自己的相机)流式传输 (RTMP) 视频