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!'")); } }