1、直接添加图片html
1.参考Qt的帮助文档,可支持的类型,便可以直接读取并显示的格式有BMP、GIF、JPG、JPEG、PNG、TIFF、PBM、PGM、PPM、XBM、XPM。windows
2.显示图片步骤:网络
先打开一个图像;将图像文件加载进QImage对象中;再用QPixmap对象得到图像;最后用QLabel选择一个QPixmap图像对象显示。app
这是要插入的图片:ide
代码以下(在这以前须要在界面里添加一个Qlabel控件,对象名为label):函数
QString filename(“F:\\Study\\junior\\Qt\\door\\1.jpg”); QImage* img=new QImage; if(! ( img->load(filename) ) ) //加载图像 { QMessageBox::information(this, tr("打开图像失败"), tr("打开图像失败!")); delete img; return; } ui->label->setPixmap(QPixmap::fromImage(*img));
显示的效果如图所示:oop
很明显只能显示图片的一小部分。ui
2、修改label的大小this
Qlable设置大小的函数有resize()spa
因此在添加图片前加上这行代码能够先调整好label的大小。
ui->label->resize(img->width(),img->height());
显示结果:
好像图片过大了,label的大小已经超过了窗口的大小,仍是不能彻底显示,因此仍是要找其余合适的解决方法。
我想label的大小范围是固定的,因此应该按比例缩放图片的大小,通过查阅资料有以下的方法:
首先用
label->setGeometry(0,0,400,300);//前两个参数表示label左上角位置后面分别是宽和高
函数设置lable的位置和大小,接着根据图片的大小缩放到合适的大小显示
图片缩放的相关函数是
img->scaled(width,height,Qt::KeepAspectRatio);
该函数前两个参数表示的是缩放以后图片的宽高,而第三个参数的做用是选择模式是否保持长宽比,相关的参数能够在qt的帮助文档中查看。接下来看使用了缩放以后的效果:
的确可以把画面所有显示出来了。下面是mainwindows的构建代码:
{ ui->setupUi(this); QString StrWidth,StrHeigth; QString filename="F:\\Study\\junior\\Qt\\door\\1.jpg"; QImage* img=new QImage,* scaledimg=new QImage;//分别保存原图和缩放以后的图片 if(! ( img->load(filename) ) ) //加载图像 { QMessageBox::information(this, tr("打开图像失败"), tr("打开图像失败!")); delete img; return; } int Owidth=img->width(),Oheight=img->height(); int Fwidth,Fheight; //缩放后的图片大小 ui->label->setGeometry(0,0,400,300); int Mul; //记录图片与label大小的比例,用于缩放图片 if(Owidth/400>=Oheight/300) Mul=Owidth/400; else Mul=Oheight/300; Fwidth=Owidth/Mul; Fheight=Oheight/Mul; *scaledimg=img->scaled(Fwidth,Fheight,Qt::KeepAspectRatio); ui->label_text->setText(QString("width: ")+StrWidth.setNum(Fwidth) +QString("\nheight: ")+StrHeigth.setNum(Fheight)); ui->label->setPixmap(QPixmap::fromImage(*scaledimg)); }
2016.9.8
目标:在Qt的实现经过按钮控制在窗口中查看mjpeg-streamer运行时本地显示的摄像头画面。
思路:原来在html中只要直接插入图片标签,对应的地址"/?action=stream" ,在打开mjpeg-streamer的时候,就能在网页中显示对应的画面,因此我想在qt的label中将该地址引用为图片是否就能够直接看到画面,接下来就直接在上次的基础上修改代码试试。
事实证实我想的太简单了,p_w_picpath.load()只能打开本地的图片,对于网上的图片只能先保存为本地的图片而后再在控件里显示,因此接下来要解决的是如何获取网络上的图片。
查阅了资料以后发现就下载而言,Qt5的QtNetwork模块为咱们提供了至关便利的接口,下面我就直接给出源码,相关的函数用法均可以参考帮助文档:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QNetworkAccessManager *manager; manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*))); QNetworkRequest request; request.setUrl(QUrl("http://www.bz55.com/uploads/allimg/150707/139-150FG51639-50.jpg")); manager->get(request); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slot_replyFinished(QNetworkReply* reply) { QPixmap pix; QByteArray data = reply->readAll(); pix.loadFromData(data, "JPG"); pix.save("/root/Qt/program/netpicture/tmp1.jpg", "JPG", 100); ui->textEdit->resize(500,500); ui->textEdit->append("<img src=/root/Qt/program/netpicture/tmp1.jpg width=400 hight=300>"); }
要注意的是在mainwindow.h里要写上
void MainWindow::slot_replyFinished(QNetworkReply* reply)
这个槽函数的声明而且加上
#include <QNetworkReply> #include <QNetworkAccessManager> #include <QNetworkRequest>
这几个头文件,在.pro文件中加上
QT+= network
这一行,接下来就能够编译运行了。
代码中连接对应的图片就显示在了textEdit控件中了,固然在
“/root/Qt/program/netpicture”目录下也成功的下载了这个图片(否则也没法显示)。
好了既然能显示网络上的图片了那就简单的修改一下源码试试在label中显示mjpeg-streamer生成的“http://localhost:8080/?action=stream”图片,若是可以显示的话只要加上循环控制应该就能够显示视频了。
2016.9.10
coding...
2016.9.11
思考:通过一天的修改折腾想要的功能基本实现了,其中和预想的不同的是要读取mjpg-streamer打开后对应的图片连接是”http://localhost:8080/?action=snapshot”
前面那个连接对应的是一个流,这才是一个静态图片。
还有一个难点是在执行了manager->get(request);并不能当即调用槽函数,因此紧接着执行在label中显示图片的语句的话会出现图片打开失败的错误提示,我想应该是向连接发出访问请求是须要一小段时间的虽然很短但仍是比两行命令之间的时间差要长不少,因此我在这两行命令之间添加了延时代码,要注意的是不能调用系统的sleep()函数,由于这样你的控件就会失去响应,固然label上的画面也就不会刷新了。
接下来就直接贴出代码,这里我也将获取到的画面自动缩放到640*480大小:
QString PU="http://192.168.253.3:8080/?action=snapshot"; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); SetWindow(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::PicConnect(QString PicUrl) { //connect to picture QNetworkAccessManager *manager; manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*))); QNetworkRequest request; request.setUrl(QUrl(PicUrl)); manager->get(request); } void MainWindow::slot_replyFinished(QNetworkReply* reply) { //save the picture QPixmap pix; QByteArray data = reply->readAll(); pix.loadFromData(data, "JPG"); pix.save("/root/Qt/program/netpicture/tmp1.jpg", "JPG", 100); } void MainWindow::SetWindow() { //set the window with one label and pushButton this->resize(800,600); ui->PicLabel->setGeometry(10,10,640,480); ui->PicLabel->setText("PICTURE......"); ui->PicButton->setGeometry(300,500,30,15); isPicOnLabel=false; ui->PicButton->setText("Show"); } void MainWindow::on_PicButton_clicked() { if(isPicOnLabel==false) { ShowPic(); } else { StopPic(); } } void MainWindow::ShowPic() { isPicOnLabel=true; ui->PicButton->setText("stop"); while(1) { if(isPicOnLabel==false) break; PicConnect(PU); QEventLoop eventloop; QTimer::singleShot(10, &eventloop, SLOT(quit())); //等待10*0.001秒 eventloop.exec(); if(! ( img->load("/root/Qt/program/netpicture/tmp1.jpg") ) ) //加载图像 { QMessageBox::information(this, tr("打开图像失败"), tr("打开图像失败!")); delete img; return; } *scaledimg=img->scaled(640,480,Qt::KeepAspectRatio); ui->PicLabel->setPixmap(QPixmap::fromImage(*scaledimg)); } } void MainWindow::StopPic() { isPicOnLabel=false; ui->PicButton->setText("show"); }
其中mainwindow.h.须要包含的头文件以及须要添加的成员变量:
#include <QMainWindow> #include <QNetworkReply> #include <QNetworkAccessManager> #include <QNetworkRequest> #include<QMessageBox> #include<QTimer> class MainWindow : public QMainWindow { Q_OBJECT public: bool isPicOnLabel; explicit MainWindow(QWidget *parent = 0); QImage* img=new QImage,* scaledimg=new QImage; ~MainWindow(); public slots: void slot_replyFinished(QNetworkReply* reply); private slots: void on_PicButton_clicked(); private: Ui::MainWindow *ui; void PicConnect(QString p); void SetWindow(); void ShowPic(); void StopPic(); };
最后能够看一下程序运行的效果:
这是在按下“show”按钮以前
按下以后:
这时候可以看到连续的画面,帧数能够经过
QTimer::singleShot(10, &eventloop, SLOT(quit()));
的第一个参数来控制,第一个参数的单位是毫秒。
为了添加拍照功能,因而加上了一个savebutton,槽函数代码以下:
void MainWindow::on_SaveButton_clicked() { if(isPicOnLabel==false) { QMessageBox::information(this, tr("ERROR!"), tr("NO PICTURE !")); } else { QString str_time,path; QDateTime time = QDateTime::currentDateTime(); str_time = time.toString("yyyy-MM-dd_hh-mm-ss"); path="../netpicture/photo/"+str_time+".jpg"; QPixmap::fromImage(*img).save(path, "JPG", 100); QMessageBox::information(this, tr("save"), tr("PICTURE has been saved to folder 'photo!'")); } }