Qt实现Image导出Json格式以及Json格式转图像

单张图像内存大,大批量图像会占用大量的内存。如果对图像中的固定ROI区域进行检测,可以将图像的roi区域转为json文件以达到降低内存的目的。利用Qt的逐个读取像素的方法速度太慢,因此采用Base64编码来转换成Json格式。

Json文本格式

"x","y","height","width"分别代表roi区域在原图像的位置,"image"是base64编码后的ROI图像。

{
    "ROIs": [
        {
            "height": 1000,
            "image": "iVBORw0KGgoAAAANSUhEUgAAA+....",
            "width": 1000,
            "x": 200,
            "y": 200
        },
        {
            "height": 1000,
            "image": "iVBORw0KGgoAAAANSUhEUgAAA....,
            "width": 1000,
            "x": 2000,
            "y": 2000
        }
    ]
}

Image转Json

思路:

(1)在创建了两个蓝色矩形区域,方便检查Json转Image的时候是否有错误。并设置ROI区域矩形的范围,

(2)对每个ROI区域单独创建QJsonObject对象,将x,y,width,height以及base64编码后的roi图像赋给QJsonObject对象。

(3)创建一个QJsonArray,循环遍历每个ROI区域并将每个ROI区域的QJsonObject对象传给QJsonArray对象。

(4)最后,通过创建QJsonDocument对象将json文件写入本地。

void MyGraphicsView::on_btn_action_ImageToJson()
{
    //创建roi区域
    QRect roi1(200, 200, 1000, 1000);
    QRect roi2(2000, 2000, 1000, 1000);
    QList<QRect> rois;
    rois.append(roi1);
    rois.append(roi2);

    // 创建4000的QImage,使用RGB888格式
    QImage blackImage(4000, 4000, QImage::Format_RGB888);

    // 将图像填充为纯黑色
    blackImage.fill(QColor(Qt::black).rgb());

    //绘制矩形
    QPainter painter(&blackImage);
    painter.setPen(Qt::red);
    painter.setBrush(Qt::blue);
    painter.drawRect(QRectF(300, 300, 800, 800));
    painter.drawRect(QRectF(2100, 2100, 800, 800));

    // 创建一个QElapsedTimer对象
    QElapsedTimer timer;

    // 启动计时器
    timer.start();

    //将图像的多个roi区域保存成json文件
    saveROIsToJson(blackImage, rois, "./black.json");

    // 计算经过的时间(毫秒)
    qint64 elapsedTime = timer.elapsed();
    qDebug() << "Image to Json time"<<elapsedTime ;

}

// 保存ROI信息和Base64图像到JSON文件
void MyGraphicsView::saveROIsToJson(const QImage& image, const QList<QRect>& rois, const QString& outputFileName)
{
    QJsonArray jsonRoiArray;
    // 遍历每个ROI区域,将它们的信息和图像Base64编码保存到JSON中
    for (const QRect& roi : rois)
    {
        if (roi.isValid()) {
            QJsonObject jsonRoi;
            //保存ROI区域的范围
            jsonRoi["x"] = roi.x();
            jsonRoi["y"] = roi.y();
            jsonRoi["width"] = roi.width();
            jsonRoi["height"] = roi.height();
    
            //对ROI区域的像素编码
            QImage roiImage = image.copy(roi);
            jsonRoi["image"] = imageToBase64(roiImage);

            jsonRoiArray.append(jsonRoi);
        }
    }


    // 创建JSON文档并保存到文件
    QJsonObject root;
    root["ROIs"] = jsonRoiArray;
    QJsonDocument jsonDoc(root);

    QFile file(outputFileName);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning() << "Couldn't open file for writing:" << outputFileName;
        return;
    }
    file.write(jsonDoc.toJson());
    file.close();
}


// 将QImage转换为Base64编码的字符串
QString MyGraphicsView::imageToBase64(const QImage& image)
{
    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG"); // 使用PNG格式保存
    return QString(byteArray.toBase64());
}

Json转Image

相反地,读取json文件,获取每个roi区域的x,y,width,height以及解码后的roi图像,利用painter对象将roi图像按原来的位置绘制。

void MyGraphicsView::on_btn_action_JsonToImage()
{
    QFile file("./black.json");
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "Couldn't open file for reading:" ;
        return;
    }

    // 创建一个QElapsedTimer对象
    QElapsedTimer timer;
    timer.start();

    // 读取 JSON 文件并解析
    QByteArray jsonData = file.readAll();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
    QJsonObject root = jsonDoc.object();


    // 创建一个与原图像大小相同的空白图像
    QImage originalImage(4000, 4000, QImage::Format_RGB888);
    originalImage.fill(Qt::white);  // 背景颜色填充为白色(或者黑色)

    // 获取所有 ROI
    QJsonArray rois = root["ROIs"].toArray();

    // 使用 QPainter 将每个 ROI 图像绘制到原始图像
    QPainter painter(&originalImage);

    for (const QJsonValue& value : rois) {
        QJsonObject jsonRoi = value.toObject();
        int x = jsonRoi["x"].toInt();
        int y = jsonRoi["y"].toInt();
        int w = jsonRoi["width"].toInt();
        int h = jsonRoi["height"].toInt();
        QString base64Image = jsonRoi["image"].toString();

        // 将 Base64 编码还原为 QImage
        QImage roiImage = base64ToImage(base64Image);

        // 将 ROI 图像绘制到原图像的对应位置
        painter.drawImage(QRect(x, y, w, h), roiImage);
    }

    painter.end();

    // 计算经过的时间(毫秒)
    qint64 elapsedTime = timer.elapsed();

    qDebug() << "Json to Image time" << elapsedTime;

    // 保存还原后的原图像
    if (!originalImage.save("a.png")) 
    {
        qWarning() << "Failed to save image";
    }
    else {
        qDebug() << "Saved restored image";
    }
}

// 将Base64字符串转换为QImage
QImage MyGraphicsView::base64ToImage(const QString& base64String)
{
    QByteArray byteArray = QByteArray::fromBase64(base64String.toUtf8());
    QImage image;
    image.loadFromData(byteArray, "PNG");
    return image;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值