目录
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
-
两者可以互相转换,实际项目里经常配合使用。