You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++98下从SQL读取Blob图片并通过QPixmap在QGraphicsView显示

问题:从数据库读取Blob图片并在QGraphicsView中显示失败

我是C++新手,尝试从SQL数据库中读取存储在.bin文件里的Blob图片,该.bin文件以字符串形式存储Blob图片(如BM6等,每个.bin仅含3-4个字符)。点击执行读取代码的按钮后,QGraphicsView并未显示Blob图片,请问如何修改代码实现Blob图片显示?

存入数据库的代码

QPixmap p;
p.load(filename);

string a = "/root/QtApplication_1/file";
string b = boost::lexical_cast<std::string>(counter);
string c = ".bmp";

p.save(("/root/QtApplication_1/file"+boost::lexical_cast<std::string>(counter)+".bmp").c_str(),"BMP");
std::string d = a + b + c ;

std::ifstream blob_file;
blob_file.open(d.c_str(), std::ios_base::binary | std::ifstream::in);

driver = get_driver_instance();
con = driver->connect("localhost","","");
con->setSchema("BitmapImagesSchema");

prep_stmt = con->prepareStatement("Insert into bitmapImagesTable(`ID`,`ImageDir`,`ImagesBitMap`) values(?,?,?)");
prep_stmt->setInt(1,counter);
prep_stmt->setString(2,d.c_str());
prep_stmt->setBlob(3,&blob_file);

prep_stmt->executeQuery();

delete prep_stmt;

读取显示的无效代码

driver = get_driver_instance();
con = driver->connect("localhost","","");
con->setSchema("BitmapImagesSchema");
stmt = con-> createStatement();

std::istream *blobData;
res = stmt->executeQuery("select `ImagesBitMap` from bitmapImagesTable where `ID`='"+boost::lexical_cast<std::string>(counter)+"'order by `ID` DESC");
while(res->last()){
    blobData = res->getBlob("ImagesBitMap");
    break;
}

std::istreambuf_iterator<char> isb = std::istreambuf_iterator<char>(*blobData);
std::string blobString  = std::string(isb,std::istreambuf_iterator<char>());
const char * image = blobString.c_str();
blobData->seekg(0,ios::end);
size_t imagesize = blobData->tellg();

cout<<"aaa="<<image<<"\n";
QPixmap p;
p.load(image);
if(!widget.graphicsView_2->scene()){
QGraphicsScene  *scene = new QGraphicsScene(this);
widget.graphicsView_2->setScene(scene);
}

widget.graphicsView_2->scene()->addPixmap(p);

delete res;
delete stmt;
delete con;

问题分析与修改方案

核心问题点

  1. QPixmap加载方式错误:QPixmap::load(const char*)是用于加载本地文件路径,你将Blob的二进制内容转成字符串后传给该函数,它会把这个字符串当作文件路径去读取,必然找不到文件,导致QPixmap为空。
  2. 结果集读取逻辑错误:while(res->last())的写法逻辑混乱,last()是将游标移到结果集最后一行,返回是否成功,这样的循环要么不执行,要么陷入死循环。
  3. 流操作无效:用istreambuf_iterator读完Blob流后,再调用seekg已经无法获取有效数据,此时流已经处于末尾位置。

修改后的代码

driver = get_driver_instance();
con = driver->connect("localhost","","");
con->setSchema("BitmapImagesSchema");
stmt = con->createStatement();

std::istream *blobData = nullptr;
res = stmt->executeQuery("select `ImagesBitMap` from bitmapImagesTable where `ID`='"+boost::lexical_cast<std::string>(counter)+"' order by `ID` DESC");

// 正确读取结果集:移动到第一行(order by DESC后即为目标行)
if (res->next()) {
    blobData = res->getBlob("ImagesBitMap");
} else {
    // 未找到数据时的处理
    cout << "未找到对应ID的图片数据" << endl;
    delete res;
    delete stmt;
    delete con;
    return;
}

// 将Blob二进制数据读取到string
std::istreambuf_iterator<char> isb(*blobData), endIter;
std::string blobString(isb, endIter);

// 将string转为QByteArray,用QPixmap从二进制数据加载
QByteArray imageData(blobString.data(), blobString.size());
QPixmap p;
// 明确指定图片格式为BMP(与存入时一致)
if (!p.loadFromData(imageData, "BMP")) {
    cout << "图片加载失败" << endl;
    delete res;
    delete stmt;
    delete con;
    return;
}

// 初始化场景并显示图片
if (!widget.graphicsView_2->scene()) {
    QGraphicsScene *scene = new QGraphicsScene(this);
    widget.graphicsView_2->setScene(scene);
} else {
    // 清空原有场景内容,避免重复添加
    widget.graphicsView_2->scene()->clear();
}
widget.graphicsView_2->scene()->addPixmap(p);
// 确保视图适配图片大小
widget.graphicsView_2->fitInView(widget.graphicsView_2->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);

// 释放资源
delete res;
delete stmt;
if (blobData) {
    delete blobData; // 注意释放Blob流资源
}
delete con;

额外说明

  • 释放资源时别忘了删除blobData,避免内存泄漏;
  • 添加fitInView可以让图片在QGraphicsView中自适应显示;
  • 加载时指定"BMP"格式,能提高加载成功率,避免QPixmap自动识别格式出错。

内容的提问来源于stack exchange,提问作者user19888430

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:25:37