QT工程中使用圖片的三種方法
圖片是一種資源,而在Qt中,對於資源的使用是有其獨特的方式的!
①:一般來說:資源在內存中是用資源對象樹來表示的,該樹在程序啓動時創建。
②:而對於資源而言:我們都是需要先將其加入到這棵樹中才能加載到內存中並被程序使用!!
③:而將一個圖片資源放到程序的資源對象樹中是用函數QResource::registerResource()來實現的。亦即:要將資源向這顆資源對象樹進行註冊,這樣纔對在系統中new創建這個資“葉子”。
Qt中經常會使用一些圖片作爲程序的界面,經常用的有三種方法,這裏借鑑了小竇朋友的方法總結
1、在程序運行時候加載圖片,
也是最簡單的方法
image=newQImage("./1.png");
這種方法在程序運行時候再去加載圖片,需要在程序的運行目錄下添加事先放置好圖片,這樣做的優點是程序運行時候不需要的圖片不加載,節省了內存,但是讀取速度慢。
2、將圖片編譯進工程中
QPixmap m_Pixmap = QPixmap(QString("://images//%AAA.png"));
ui.label->setPixmap(m_Pixmap);
ui.label->resize(m_Pixmap.width(),m_Pixmap.height());
或
//將圖像文件加載進QImage對象中
QImage* imgSource = new QImage(QString("://images//%AAA.png"));
QImage* imgScaled = new QImage();
// 圖像縮放 指定圖片的寬和高,根據縱橫比模式和轉換模式從原有圖像返回一個經過比例轉換的圖像
*imgScaled = imgSource->scaled(400,300,Qt::KeepAspectRatio);
ui.label->setMaximumSize(400,300);
// QPixmap對象獲得圖像,QLabel顯示QPixmap圖像
ui.label->setPixmap(QPixmap::fromImage(*imgScaled));
這樣在程序發佈時候不需要在目錄下放置圖片,主要通過的是.qrc文件,例如添加image.qrc文件,這個文件會在編譯時候生成qrc_image.cpp文件,,我們可以自己看下這個生成的cpp文件,發現其中就是主要有三個static const數組。
qt_resource_data[]
qt_resource_name[]
qt_resource_struct[]
這其中qt_resource_data[]中存放的就是圖片的二進制數據。而後邊的兩個數組我們猜測是做了一個圖片名字到上邊數據的映射,方便系統找到data中的二進制數據。
至於內部作用機制,有的資料上說是:當使用qrc資源文件時,系統會自動將所有的圖片資源都向程序的資源對象樹進行註冊,並且當程序結束運行時再進行反註冊。這也正好解釋了爲什麼此種方法下圖片資源會一直佔用內存的原因。
使用這種方法時:由於圖片資源一直在內存中,避免了I/O操作,從而加快了讀取速度。但是卻是以消耗內存爲代價的
方法如下:
在qrc文件中加上下面的代碼。
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>1.png</file>
<file>2.ico</file>
</qresource>
</RCC>
然後再.pro文件中添加下面的代碼
RESOURCES = res.qrc
在程序中使用圖片文件時候,通過
:1.png的方法來使用
例如
image=new QImage("://1.png");
3、手動進行註冊
第二種方法相當於靜態加載,但很多情況下我們更希望是動態加載,亦即:用到哪個資源纔將該資源加載進來,而不用的則不加載。
上邊第二種方法之所以顯示出靜態加載的特性,這是由於系統一次性自動把所有圖片資源都進行了註冊,並且在程序運行過程中一直沒有進行反註冊才導致的。 如果我們可以自行決定:什麼時候對那一部分圖片資源進行註冊?什麼時候對哪一部分圖片資源進行反註冊。則顯然我們可以手動控制整個資源在內存中的生存週期!!
這種方法的主要步驟爲:
①:生成外部二進制資源文件。
②:在需要時將該資源向程序的資源對象樹進行註冊並使用。
③:在不需要時進行反註冊。
步驟①主要是用了Qt自帶的一個工具:rcc.exe (處於bin文件夾中)。這是Qt的一個資源編譯器,其編譯對象是qrc文件,而生成rcc二進制資源文件。
那我們可以用它來執行命令 rcc -binary name.qrc -o name.rcc 來把qrc資源文件轉成rcc二進制資源文件。
而後在程序內部:當需要使用某一圖片資源時:則直接調用
QResource::registerResource(“name.rcc”)進行註冊創建分配內存即可! 而不使用時候則調用反註冊函數!!
這種方式算是動態加載,會少佔用內存。但是如果圖片過多的話,什麼時候需要加載,什麼時候需要去掉,這些邏輯就需要十分注意了