Я использую:
- C ++ Builder (RAD Studio 10.2)
- SQLite 3
Попытка сохранить изображение PNG в базе SQLite и тогда верни это. Я читаю форумы уже три дня, но не могу найти решение.
Вот мой код:
Код для записи изображений
AnsiString Insert_data;
UnicodeString Path;
int rc,filesize,rowid;
sqlite3 *db;
sqlite3_stmt *insert_stmt;
sqlite3_blob *blob;
if(OpenDialog1->Execute())
{
Memo1->Lines->Add(OpenDialog1->FileName);
Image1->Picture->LoadFromFile(OpenDialog1->FileName);
}
sqlite3_open16(base_name.c_str(), &db);
Path = OpenDialog1->FileName;
TFileStream *f = new TFileStream(Path, fmOpenRead);
filesize = f->Size;
Memo1->Lines->Add("Вес файла : " + (String)filesize);
f->Position = 0;
Insert_data = "INSERT INTO images(id, pic_id, picture_name, data) VALUES (?, ?, ?, ?);";
rc = sqlite3_prepare_v2(db, Insert_data.c_str(), -1, &insert_stmt, NULL);
if(rc != SQLITE_OK)
{
Memo1->Lines->Add(sqlite3_errmsg(db));
sqlite3_close(db);
}
sqlite3_bind_int(insert_stmt, 1, 1);
sqlite3_bind_int(insert_stmt, 2, 1);
Insert_data = OpenDialog1->FileName;
sqlite3_bind_text(insert_stmt, 3, Insert_data.c_str(), -1, 0);
sqlite3_bind_zeroblob(insert_stmt, 4, filesize);
// sqlite3_bind_blob(insert_stmt,4,f, f->Size,SQLITE_STATIC); // That doesn't work too
rc = sqlite3_step(insert_stmt);
if(rc != SQLITE_DONE)
{
Memo1->Lines->Add("Insert statement didn't work");
Memo1->Lines->Add(sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
sqlite3_reset(insert_stmt);
rowid = sqlite3_last_insert_rowid(db);
rc = sqlite3_blob_open(db, "main", "images", "data", rowid, 1, &blob);
if(rc != SQLITE_OK)
{
Memo1->Lines->Add(sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
Memo1->Lines->Add("size of BLOB : " + (String)sqlite3_blob_bytes(blob));
rc = sqlite3_blob_write(blob, f, f->Size, 0);
if(rc != SQLITE_OK)
{
Memo1->Lines->Add("Error write " + IntToStr(error));
Memo1->Lines->Add(sqlite3_errmsg(db));
}
rc = sqlite3_blob_close( blob );
if(rc != SQLITE_OK)
{
Memo1->Lines->Add("Error close " + IntToStr(error));
Memo1->Lines->Add(sqlite3_errmsg(db));
}
Код чтения изображения
sqlite3 *db;
sqlite3_blob *data;
int rc, bytes;
int error = -100;
sqlite3_open("game_data",&db);
rc = sqlite3_blob_open(db,"main","images","data",1,0,&data);
if(rc != SQLITE_OK)
{
Memo1->Lines->Add(sqlite3_errmsg(db));
sqlite3_close(db);
return;
}
bytes = sqlite3_blob_bytes(data);
char *zBlob = (char *) malloc(bytes);
error = sqlite3_blob_read(data,zBlob,bytes,0);
if(error != SQLITE_OK)
{
Memo1->Lines->Add("Error open " + IntToStr(error));
Memo1->Lines->Add(sqlite3_errmsg(db));
}
TMemoryStream *ms = new TMemoryStream();
ms->Write(zBlob, bytes);
ms->Position = 0;
Memo1->Lines->Add("read: " + IntToStr(bytes));
//Image1->Picture->LoadFromStream(ms); // error
ms->SaveToFile("123.png");
sqlite3_close(db);
//delete []ms;
Кажется, что записано и прочитано, размер в байтах одинаков, но полученный файл 123.png не читается как рисунок. Что-то где-то потеряно, я не могу понять, в чем проблема.