Qt實現圖片的簡單壓縮

在編程過程中,涉及到網絡傳輸或資源加載時,過大的圖片往往是編程人員的噩夢,加載時間過長,體驗效果差,特別在即時通訊的發送圖片時,大圖往往半天加載不出來,於是,先對圖片進行壓縮,暫時顯示模糊圖片,然後下載大圖最後更新下載的大圖,這一過程成爲解決大圖片加載過慢體驗效果差的關鍵。
QImage提供了縮放圖片的函數scaled,並且可以用參數指定”快速縮放(FastTransformation)”還是”平滑縮放(SmoothTransformation)”, 使用還是很方便的。 但是如果你用縮放函數去做大圖片的縮略圖可能會發現”快速縮放”得到的圖片質量不佳, 而”平滑縮放”質量很好但速度欠佳, 特別是原圖非常大的時候smoothscale簡直就是個噩夢阿。 這裏就可以使用被稱爲“Cheat Scaling”的縮小圖片的技巧了, 那就是先使用”快速縮放”得到一箇中等大小的圖片以獲得較快的縮放速度, 再使用”平滑縮放”縮小至需要的大小以獲得較好的圖片質量。
實現代碼如下:
#include <QFile>
void compressImg()
{
QImage img;
img.load("./in.jpg");
QImage result = img.scaled(800, 600, Qt::KeepAspectRatio, Qt::FastTransformation).scaled(260, 140, Qt::KeepAspectRatio, Qt::SmoothTransformation);
bool isSuccess = result.save("out.jpg", "JPEG", 100);
if (!isSuccess)
{
qDebug() << "save image fail!";
}
QFile file("out.jpg");
qint64 fsz = file.size();


int quality = 100;
while (fsz > 2048)
{
quality = quality - 5;
isSuccess = result.save("out.jpg", "JPEG", quality);
if (!isSuccess)
{
qDebug() << "save image fail! quality=" << quality;
}
fsz = file.size();
qDebug() << "+++++++++++++++++++++++quality=" << quality;
if (quality <= 0)
break;
}
}
通過壓縮,可以將圖片壓縮至2K(2048字節)以內,此時,圖片的質量有明顯的下降,但是解決了大圖片下載耗時的問題。
以上代碼,先通過QImage的scaled()方法將圖片縮放到260x140,然後通過save的quality參數將圖片的質量下調,直至圖片文件大小滿足要求(2K以內)。使用技巧是調用scaled()將圖片縮放至中等圖片img.scaled(800, 600, Qt::KeepAspectRatio, Qt::FastTransformation)時,使用的transformMode爲Qt::FastTransformation進行快速壓縮,然後在進行二次縮放scaled(260, 140, Qt::KeepAspectRatio, Qt::SmoothTransformation)時,使用transformMode爲Qt::SmoothTransformation進行縮放,這樣既保障圖片的質量,又提高了壓縮速度。
實現了壓縮以後,要對圖片進行讀取,通過字節形式進行發送,然後在接收端對數據進行保存並顯示模糊的壓縮圖片,代碼如下:
#include <QFile>
void saveImg() {
QFile file("out.jpg");
file.open(QIODevice::ReadOnly);
QByteArray arr = file.readAll();
file.close();
char* p = arr.data();


//file.remove();


QImage aout;
aout.loadFromData(arr);
aout.save("aout.jpg", "JPEG", 100);


QFile file_out("aout.jpg");
fsz = file_out.size();
quality = 100;
while (fsz > 2048)
{
quality = quality - 5;
isSuccess = aout.save("aout.jpg", "JPEG", quality);
fsz = file_out.size();
qDebug() << "+++++++++++++++++++++++quality=" << quality;
if (quality <= 0)
break;
}
}
用QFile的readAll()方法可以將圖片以文件形式全部讀出,返回一個QByteArray保存讀出的數據,即爲圖片的二進制數據,也可以用QByteArray的data()方法將數據轉換爲char*指針,且該指針是以'\0'結尾的,因此可以通過網絡對較少字節的數據進行傳輸。

用QImage的loadFromData()方法對讀出的QByteArray進行加載並保存爲aout.jpg文件,當用aout.save("aout.jpg", "JPEG", 100);對保存的2K數據轉換爲圖片aout.jpg時,設置quality爲100,輸出圖片aout.jpg的大小竟然變大了(7K左右),但是圖片的質量依然和原始的2K圖片質量一樣,因此,最後最圖片又進行了循環保存,以減少不必要的空間浪費。

效果圖如下:

壓縮前:1.4M   4208*3120


壓縮後:1.98K   188*140


瞭解更多關於Qt、QML、Linux、MacOSX相關技術,請掃碼關注【三個程序員】接收實時消息^_^.


發佈了58 篇原創文章 · 獲贊 83 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章