目錄
1、一般圖片瀏覽軟件的流程(Qt 或類似框架):
1?? 讀取原始數據
2?? 解析圖片格式
3?? 存儲到內部可用的繪制對象
4?? 顯示到界面
? 總結
2、那什么叫“QPixmap 在 Qt 里就是“顯示專用的像素緩存”,不是原始壓縮文件,這句話什么意思
2?? 舉個比喻
3?? 為什么 Qt 這么做
3、如果想將sqlite3中存儲的圖片讀取出來,并顯示?
👌 這個需求可以分三步走:
從 SQLite 數據庫讀取圖片二進制數據(BLOB)
轉成 Qt 可用的 QPixmap/QImage
在控件里顯示(QLabel、paintEvent、QGraphicsView 等)
1. 假設數據庫中存儲了圖片
2. 在 Qt 中讀取 BLOB 數據
3. 關鍵點解釋
? 總結
4、Qt中?QPixmap和QImage有什么不同?
1. 核心區別
2. 為什么顯示用 QPixmap
3. 例子:兩者配合使用
4. 結論
1、一般圖片瀏覽軟件的流程(Qt 或類似框架):
1?? 讀取原始數據
-
圖片文件存在磁盤上(PNG、JPG、BMP 等),瀏覽器需要先加載二進制數據。
-
方式:
-
從文件系統讀取(常規圖片)
-
從數據庫或網絡加載(BLOB / HTTP / FTP 等)
-
QByteArray data;
QFile file("cat.png");
file.open(QIODevice::ReadOnly);
data = file.readAll();
2?? 解析圖片格式
-
根據文件頭(magic number)或文件擴展名識別格式:
-
PNG:
89 50 4E 47 0D 0A 1A 0A
-
JPG:
FF D8 FF
-
-
使用圖像庫(Qt 內置、libjpeg、libpng 等)把二進制數據解碼成像素信息。
QPixmap pix;
pix.loadFromData(data); // Qt 自動識別格式并解碼
3?? 存儲到內部可用的繪制對象
-
Qt:
QPixmap
(硬件加速,顯示優化) -
像素處理軟件:
QImage
(CPU 內存中,便于像素級操作) -
這一步的作用是把文件格式(壓縮、編碼)轉換成位圖像素,便于繪制。
4?? 顯示到界面
-
使用
QPainter::drawPixmap()
或QLabel::setPixmap()
把像素顯示出來 -
Qt 會盡量用顯卡加速渲染,提高顯示效率
-
如果圖片縮放、旋轉,也是在這個階段處理。
label->setPixmap(pix.scaled(label->size(), Qt::KeepAspectRatio));
? 總結
-
瀏覽器或圖片查看器基本都是這個流程:
文件 / 網絡 / 數據庫 → 讀取二進制 → 解碼成像素 → 顯示 -
QPixmap
在 Qt 里就是**“顯示專用的像素緩存”**,不是原始壓縮文件 -
原格式信息(PNG、JPG)在顯示時已經不重要了,除非你要保存或導出
2、那什么叫“QPixmap 在 Qt 里就是“顯示專用的像素緩存”,不是原始壓縮文件,這句話什么意思
1?? 原始壓縮文件 VS 像素緩存
-
原始壓縮文件
-
例如
cat.png
、dog.jpg
。 -
文件在磁盤上存儲的是 壓縮編碼的數據,不是直接的像素。
-
PNG 用 DEFLATE 壓縮 + 顏色索引
-
JPG 用 DCT + 有損壓縮
-
-
文件本身并不是每個像素的顏色值,而是經過壓縮、編碼過的。
-
讀取這個文件需要 解碼 才能得到真正的像素顏色信息。
-
-
像素緩存(QPixmap)
-
QPixmap
內部存儲的是 解碼后的每個像素的顏色值(RGBA 或 RGB)。 -
就是屏幕上顯示的原始像素數據,已經不再是 PNG/JPG 壓縮格式。
-
Qt 可以直接把這些像素交給顯卡渲染,不需要再解碼。
-
2?? 舉個比喻
想象一下:
-
原始文件 = 一本壓縮過的書(壓縮包)
-
解壓后的像素緩存(QPixmap) = 打開壓縮包后的書頁,文字/圖片已經完整展開
-
屏幕顯示 = 把書頁貼到墻上展示
你不能直接把壓縮包貼到墻上看(顯示不了內容),必須先解壓。QPixmap 就是“解壓后的內容,專門為顯示準備的”。
3?? 為什么 Qt 這么做
-
顯示圖片時,如果每次都去解壓 PNG/JPG,會非常慢。
-
QPixmap 把像素緩存在顯存里,繪制時直接交給 GPU → 渲染速度快。
-
它是 顯示專用,不是文件的存儲形式,所以修改 QPixmap 并不會改變原文件。
💡 總結
QPixmap ≈ “已經解碼好的像素緩存”,用于顯示
PNG/JPG 文件 ≈ “壓縮編碼文件”,用于存儲
兩者存儲內容和用途不同
所以,我們平時使用圖片查看器看到的圖像都是解壓后的數據呈現的像素效果。
3、如果想將sqlite3中存儲的圖片讀取出來,并顯示?
👌 這個需求可以分三步走:
-
從 SQLite 數據庫讀取圖片二進制數據(BLOB)
-
轉成 Qt 可用的 QPixmap/QImage
-
在控件里顯示(QLabel、paintEvent、QGraphicsView 等)
1. 假設數據庫中存儲了圖片
SQLite 表結構可能是這樣的:
CREATE TABLE images (id INTEGER PRIMARY KEY,name TEXT,data BLOB
);
存的時候一般是用二進制流寫進去。
2. 在 Qt 中讀取 BLOB 數據
使用 QSqlQuery 取出數據,再轉成 QByteArray
→ QPixmap
。
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include <QDebug>
#include <QPixmap>
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>class ImageWidget : public QWidget {Q_OBJECT
public:ImageWidget(QWidget *parent = nullptr) : QWidget(parent) {QVBoxLayout *layout = new QVBoxLayout(this);QLabel *label = new QLabel(this);layout->addWidget(label);// 1. 打開數據庫QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("mydata.db");if (!db.open()) {qDebug() << "數據庫打開失敗:" << db.lastError().text();return;}// 2. 查詢 BLOBQSqlQuery query("SELECT data FROM images WHERE id=1");if (query.next()) {QByteArray blob = query.value(0).toByteArray();// 3. 轉 QPixmapQPixmap pix;pix.loadFromData(blob);// 4. 顯示在 QLabellabel->setPixmap(pix.scaled(300, 300, Qt::KeepAspectRatio));} else {qDebug() << "未找到記錄";}}
};
3. 關鍵點解釋
-
QByteArray blob = query.value(0).toByteArray();
SQLite 里存的 BLOB → 直接轉 QByteArray。 -
pix.loadFromData(blob)
Qt 會自動根據圖片頭(PNG/JPG/BMP 等)解析格式。 -
顯示
最簡單的是用QLabel::setPixmap()
,也可以在paintEvent
里用QPainter::drawPixmap()
。
? 總結
-
SQLite 里存圖片 → BLOB 類型
-
取出后用
QPixmap::loadFromData()
轉換 -
用
QLabel
或QPainter
繪制
4、Qt中?QPixmap和QImage有什么不同?
1. 核心區別
特性 | QPixmap | QImage |
---|---|---|
存儲方式 | 依賴底層圖形系統(GPU/顯存加速) | 存在內存中(CPU 管理的像素數組) |
優化方向 | 顯示優化(繪制到屏幕最快) | 像素級操作優化(修改、訪問像素快) |
典型用途 | 用于繪制 UI、顯示圖片、圖標 | 圖像處理(濾鏡、像素修改、OCR 前處理) |
線程安全 | GUI 線程專用(不能在非 GUI 線程創建/使用) | 可在非 GUI 線程使用 |
轉換方式 | 可由 QImage 轉換而來 | 可由 QPixmap 轉換而來 |
2. 為什么顯示用 QPixmap
-
QPixmap
會把圖像數據交給底層圖形系統(X11、Windows GDI、OpenGL、Raster),顯示時 直接調用顯卡加速,效率很高。 -
QImage
是存在普通內存里的,繪制時要先拷貝到顯存,顯示性能差很多。 -
因此 Qt 官方建議:
-
顯示/繪制 → QPixmap
-
處理/計算 → QImage
-
3. 例子:兩者配合使用
比如從 SQLite 讀出一張 BLOB:
QByteArray blob = query.value(0).toByteArray();
QImage img;
img.loadFromData(blob); // 先用 QImage 讀出來
QPixmap pix = QPixmap::fromImage(img); // 轉換成 QPixmap
label->setPixmap(pix); // 顯示
如果要對圖像做濾波、灰度化之類的操作,就在 QImage
階段完成,最后再轉成 QPixmap
。
4. 結論
-
顯示(UI、繪制到屏幕)→ 用 QPixmap
-
處理(圖像計算、像素訪問)→ 用 QImage
-
兩者可以互相轉換,實際項目里經常配合使用。