我试图连续捕获图像,以便可以使用UDP发送图像。我这样做是为了实现实时视频流程序。
下面的代码连续捕获图像并将图像分配给QGraphicsScene,因此我可以测试图像是否像视频一样播放。但是,当我运行程序时,即使删除了指针,计算机也会在几秒钟后死机。我该如何解决这个问题?
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->setScene(scene);
cam = new QCamera;
cam->setCaptureMode(QCamera::CaptureStillImage);
viewfinder = new QCameraViewfinder;
viewfinder->show();
QCameraImageCapture *cap = new QCameraImageCapture(cam);
cap->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
cam->setViewfinder(viewfinder);
QObject::connect(cap, &QCameraImageCapture::imageCaptured, [=] (int id, QImage img) {
while(true){
QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;
QThread::sleep(0.0416);
cap->capture();
}
});
QObject::connect(cap, &QCameraImageCapture::readyForCaptureChanged, [=] (bool state) {
if(state == true) {
cam->searchAndLock();
cap->capture();
cam->unlock();
}
});
cam->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
答案 0 :(得分:0)
我不熟悉QCamera
和相关类,但是您将lambda
信号连接到的QCameraImageCapture::imageCaptured
看起来不正确。当单帧准备预览时,将发出该信号。但是,在您的lambda
中,您有...
while(true){
QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;
QThread::sleep(0.0416);
cap->capture();
}
该while
循环永远不会退出,并且将阻塞Qt
事件处理循环。还要注意,代码块...
QByteArray *buf = new QByteArray;
QBuffer *buffer=new QBuffer(buf);
buffer->open(QIODevice::WriteOnly);
img.save(buffer, "BMP");
QPixmap *pixmap = new QPixmap();
pixmap->loadFromData(buffer->buffer());
scene->addPixmap(*pixmap);
delete buf;
delete buffer;
delete pixmap;
是过度杀伤力,(除非我弄错了),基本上等于...
scene->addPixmap(QPixmap::fromImage(img));
所以我认为您的lambda
应该更像(未经测试)...
[=](int id, QImage img)
{
scene->addPixmap(QPixmap::fromImage(img));
}
答案 1 :(得分:0)
您应该使用imageAvailable()而不是imageCaptured信号。
这里是一个例子:
connect(cap, &QCameraImageCapture::imageAvailable, [=] (int id, QVideoFrame v ) {
if (v.isValid()) {
if(v.map(QAbstractVideoBuffer::ReadOnly)) {
QByteArray bitsVideo( (char *) v.bits(), v.mappedBytes() );
//call to your send raw data function (over UDP) :
//datagram will contain frame details e.g : [ width, hight, byteperline, format, rawdata ]
sendDataOverUDP( v.width(), v.height(),
v.bytesperLine(),
QVideoFrame::imageFormatFromPixelFormat(v.pixelFormat()),
bitsVideo );
}
}
});
另一端,服务器或其他客户端将从接收到的原始数据创建图像,如下所示:
void onDataImageReceived( int width, int height,
int bytePerLine,
QImage::Format fmt,
QByteArray bitsVideo )
{
QImage img ((uchar *)bitsVideo.data(), width, height, bytesPerLine, fmt);
//do something with img ...
}