Qt以Json(JsonArray)格式向数据库添加图片数据(十六进制)及回显(序列化及反序列化)(解决方案)

这是一篇关于讲解"Qt以Json(JsonArray)格式向数据库添加图片数据(十六进制)及回显"的解决方案。

原因

在进行编程时,想将本地图片资源以Json格式保存到数据库,这样在不同的终端,都可以使用该数据库读取图片。

实现之前,先上网查下是否有可用示例,经过查阅,发现只有单个图片的序列化存储。而无以JsonArray进行存储的示例。既然没有,那就只有自己实现了。

说做就做,先将需求分解:

  1. 数据库表设计
  2. 数据的存储
  3. 数据的读取

实现

1. 数据库表设计

既然用于测试,那就随机创建个3列的表吧,关于对图片资源的字段类型,可以设置为TEXT。

cpp 复制代码
    QSqlDatabase m_db = QSqlDatabase::addDatabase("QSQLITE", "pngJsonArrayTest");
    if (!m_db.driver()->hasFeature(QSqlDriver::Transactions)) {
        qDebug() << "Database does not support transactions.";
        // handle lack of transaction support
    }
    m_db.setDatabaseName("./pngJsonArrayTest.db");
    m_db.open();

    QSqlQuery query(m_db);
    QString strQuery = QString("create table '%1' ('%2' TEXT,'%3' TEXT,'%4' TEXT)").arg("goodLucky", "f1", "f2", "pngJsonInfo");
    query.exec(strQuery);

2. 数据的存储

在进行存储前,首先得知道JsonValue、JsonArray和QByteArray的用法。

2.1 QJsonValue
cpp 复制代码
    QJsonValue(Type = Null);
    QJsonValue(bool b);
    QJsonValue(double n);
    QJsonValue(int n);
    QJsonValue(qint64 n);
    QJsonValue(const QString &s);
    QJsonValue(QLatin1String s);
    QJsonValue(const QJsonArray &a);
    QJsonValue(const QJsonObject &o);

QJsonValue存储的类型除了基本类型,还可以存储QJsonArray和QJsonObject.

2.2 QJsonArray

QJsonArray存储数据有很多个接口,以下是两种常用的。

cpp 复制代码
void QJsonArray::insert(int i, const QJsonValue &value);

在数组的索引位置i插入值。如果i为0,则将该值添加到数组中。如果i是size(),则该值被附加到数组中。

cpp 复制代码
void QJsonArray::push_back(const QJsonValue &value);

这个函数是为了兼容STL而提供的。它相当于append(value),将值追加到数组中。

2.2 QByteArray

QByteArray可用于存储原始字节(包括'\0')和传统的8位'\0'结尾的字符串。使用QByteArray比使用const char *方便得多。在后台,它总是确保数据后跟一个'\0'结束符,并使用隐式共享(写时复制)来减少内存使用并避免不必要的数据复制。

除了QByteArray, Qt还提供了QString类来存储字符串数据。在大多数情况下,QString是想要使用的类。它存储16位Unicode字符,使得在应用程序中存储非ascii /非latin -1字符变得容易。此外,QString在整个Qt API中使用。适合使用QByteArray的两种主要情况是:当需要存储原始二进制数据时,以及当内存保存非常重要时(例如,使用用于嵌入式Linux的Qt)。
QByteArray的用法和QString类似。

根据以上,可以看出,Json不可以存储QByteArray类型的数据。

因此我们要做的是,对QByteArray二进制或十六进制类型的数据的转换。

网上有很多QByteArray转QString的方法,但是基本都是对于文本字符串的,例如:QByteArray byte("Hello");

如果QByteArray为十六进制的数据,不能直接转化为QString,因为遇到\0时QString(str)转化时要么输出会为空,要么会缺失数据。

3. 数据的读取

查阅QByteArray帮助手册,发现其提供的有转换为16进制的接口:toHex()fromHex()

接下来就是具体实现:

3.1 存储
cpp 复制代码
// 序列化
        m_db.transaction();
        QJsonArray array;
        for(int i = 0; i < 3; ++i)
        {
	    // 资源路径
            QString strPath = "xxxx.png";
            QPixmap pixmap(strPath);
            QByteArray byteArray;
            QBuffer buffer(&byteArray);
            buffer.open(QIODevice::WriteOnly);
            QDataStream out(&buffer);
            out << pixmap;
            array.push_back(QString::fromLatin1(byteArray.toHex()));
        }
        QJsonDocument doc(array);
        QByteArray byteArray1 = doc.toJson();
        QSqlQuery query(m_db);
        query.prepare("INSERT INTO goodLucky (f1, f2, pngJsonInfo) "
                      "VALUES (:f1, :f2, :pngJsonInfo)");
        query.bindValue(":f1", "1");
        query.bindValue(":f2", "2");
        query.bindValue(":pngJsonInfo", byteArray);
        query.exec();
        m_db.commit();

经过以上转换,存储到数据库的就是十六进制的字符串。

3.3 读取
cpp 复制代码
// 反序列化
    QSqlQuery query("SELECT * FROM goodLucky", m_db);
    query.exec();

    while (query.next()) {
        QByteArray byteArray = query.value(2).toByteArray();
        QJsonDocument doc = QJsonDocument::fromJson(byteArray);
        for(QJsonValue value : doc.array()){
            QByteArray ba =  QByteArray::fromHex(value.toString().toLatin1()); 
            QBuffer buffer(&ba);
            buffer.open(QIODevice::ReadOnly);
            QDataStream in(&buffer);
            QPixmap pixmap;
            in >> pixmap;
        }
    }

以上就是反序列化过程。

结论

经过以上操作,就可以实现以JsonArray方式储存图片资源的十六进制形式。

Tips

如果数据库每个字段只是存储一个图片资源,直接可以储存不转换的QByteArray对象。

相关推荐
无己心3 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u0103055279 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055279 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝11 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552711 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552711 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552714 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552714 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552715 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节
u01030552716 天前
Java模块化编程实战指南
人工智能·笔记·1024程序员节