Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
8 / 7 / 3
Регистрация: 05.02.2010
Сообщений: 146
1

Чтение/запись картинки в SQLITE через BLOB

26.02.2020, 03:53. Просмотров 1667. Ответов 1
Метки нет (Все метки)


Читаю .png файл и записываю в BLOB SQLite:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    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 (?, ?, ?, ?);";
        // компилируем SQL запрос в БАЙТ код
        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);
        // связываем BLOB длины filesize , который заполняется нулями
        sqlite3_bind_zeroblob(insert_stmt, 4, filesize);
//      sqlite3_bind_blob(insert_stmt,4,f, f->Size,SQLITE_STATIC); // Так тоже не работает
        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("Длина 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 ); // закрытие Blob
        if(rc != SQLITE_OK)
        {
            Memo1->Lines->Add("Error close " + IntToStr(error));
            Memo1->Lines->Add(sqlite3_errmsg(db));
        }
Забираю BLOB из SQLite и сохраняю в png:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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); // открываем блоб, бд main c таблицей img, поле img и id = 1
        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("Прочитано: " + IntToStr(bytes));
//Image1->Picture->LoadFromStream(ms); // Ошибка
ms->SaveToFile("123.png");
 
 
sqlite3_close(db); //Закрываем БД
//delete []ms; // Удаляем поток
Вроде оно пишется и читается, размер в байтах совпадает, но итоговый файл 123.png не читается как картинка. Где-то что-то теряется, не могу понять в чем проблема(
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2020, 03:53
Ответы с готовыми решениями:

Запись Blob объекта в БД через SQLite 3.0
Имеется БД, в которой есть таблица Chart, у нее 2 поля, id - первичный ключ, data - BLOB . Задача...

Чтение Blob поля с DBF файлами из FDB и их запись в dataGrigView
Есть таблица в базе данных Firebird, у которой есть поле типа Blob и в котором (прошу прощения за...

Работа с БД SQLite 3: чтение, запись
есть бд SQLite 3, раньше с SQLite не работал, подскажите как от туда считать данные и записать их...

Как организовать чтение/запись в SQLite?
Приветствую всех! Пишу небольшую утилитку на Java в IDEA CE. Имеется на диске sqlite-файл....

__________________
Помогаю в написании студенческих работ здесь.
Записывайтесь на профессиональные курсы C++ разработчиков
1
8 / 7 / 3
Регистрация: 05.02.2010
Сообщений: 146
02.04.2020, 00:41  [ТС] 2
Лучший ответ Сообщение было отмечено nick42 как решение

Решение

Так, проблему я решил, она была на этапе записи.
Для тех кто наткнется на эту тему в поисках решения:
Вместо самого TFileStream:
C++
1
rc = sqlite3_blob_write(blob, f, f->Size, 0);
Нужно отдавать буфер из памяти:
C++
1
2
3
4
5
6
7
8
char *vchrgBuf; 
    if ((vchrgBuf = (char *) malloc(f->Size)) == NULL)
    {
        //Здесь можно поместить сообщение об ошибке выделения памяти
        return;
    }
f->Read(vchrgBuf,f->Size);
rc = sqlite3_blob_write(blob, vchrgBuf, f->Size, 0);
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.04.2020, 00:41

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Чтение и запись данных в локальную БД SQLite
Есть вот такой класс для работы локальной работы с БД. package...

Запись в blob-поле изображений через openfiledialog Lazarus
Необходимо брать картинки через openfiledialog и по нажатию на кнопку записывать файлик в blob-поле...

Картинки в ini-file. Не верные чтение или запись?
При чтении предварительно записанных изображений из ini-файла в TImage картинка в формате BMP...

Структура в Blob SQLite
Приветствую, Существует структура <matrix<float,0,1>> VectorsForDB; Как можно эту структуру...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.