Подтвердить что ты не робот

Чтение и запись изображений в SQLite DB для использования iPhone

Я создал SQLite DB, который в настоящее время отлично читает и записывает NSString. Я также хочу сохранить изображение в базе данных и напомнить его позже. Я немного поработал с использованием NSData и кодирования изображения, но я не совсем уверен, что такое синтаксис для того, что я хочу делать. Любые фрагменты кода или примеры будут с благодарностью оценены.

Мой текущий процесс выглядит следующим образом: UIImagePickerController → Пользователь выбирает изображение из фотографий → selectedImage устанавливается в экземпляр UIImageView Теперь я хочу взять это изображение и сохранить его в DB

Я должен упомянуть, что этот вызов в конечном итоге будет заменен вызовом удаленного сервера. Не уверен, что это имеет значение с точки зрения производительности.

4b9b3361

Ответ 1

Один вариант (и, как правило, предпочтительный при работе в SQL) заключается в том, чтобы записать изображение в файл в системе и сохранить путь (или какой-либо другой идентификатор) в базе данных.

Ответ 2

Вам нужно будет преобразовать UIImage, размещенный в вашем UIImageView, в двоичный BLOB для хранения в SQLite. Для этого вы можете использовать следующее:

NSData *dataForImage = UIImagePNGRepresentation(cachedImage);
sqlite3_bind_blob(yourSavingSQLStatement, 2, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT);

Это создаст представление PNG вашего изображения, сохранит его в экземпляре NSData и привяжет байты из NSData как BLOB для второго аргумента в вашем SQL-запросе. Используйте UIImageJPEGRепредставление в приведенном выше для хранения в этом формате, если хотите. Вам нужно будет добавить столбец BLOB в соответствующую таблицу в вашей базе данных SQLite.

Чтобы получить это изображение, вы можете использовать следующее:

NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)];       
self.cachedImage = [UIImage imageWithData:dataForCachedImage];
[dataForCachedImage release];

Ответ 3

Рекомендация Apple заключается не в том, чтобы хранить BLOB в базах данных SQLite, превышающих ~ 2 килобайта.

SQLite организует базы данных на страницах. Каждая страница имеет размер 4 килобайта. Когда вы читаете данные из файла базы данных SQLite, он загружает эти страницы в внутренний кеш страниц. На iPhone я думаю, что этот кеш по умолчанию имеет размер 1 мегабайт. Это делает чтение смежных записей очень быстрым, потому что они, вероятно, уже будут в кэше страниц.

Когда SQLite считывает вашу запись базы данных в память, она считывает всю запись и все страницы, которые она занимает. Поэтому, если ваша запись содержит BLOB, она может занимать много страниц, и вы будете выталкивать существующие страницы из кеша и заменять их вашими блоками записи BLOB.

Это не так уж плохо, если вы просто просматриваете и загружаете все свои BLOBS, чтобы что-то делать с ними (покажите их, например). Но если вы сказали, что выполнили запрос, в котором вы хотели получить некоторые данные, расположенные в той же строке, что и BLOB, этот запрос будет намного медленнее, чем если бы запись не содержала большой BLOB.

Итак, как минимум вы должны хранить данные BLOB в отдельной таблице. Например:

CREATE TABLE blobs ( id INTEGER PRIMARY KEY, data BLOB );
CREATE TABLE photos ( id INTEGER PRIMARY KEY, name TEXT, blob_id INTEGER, 
    FOREIGN KEY(blob_id) REFERENCES blobs(id) );

Или еще лучше сохранить данные BLOB как файлы вне базы данных SQLite.

Обратите внимание, что может быть возможно настроить размер кеша страницы с помощью инструкций SQL PRAGMA (если вы не используете CoreData).

Ответ 4

Написание образа на SQLite DB

if(myImage != nil){
    NSData *imgData = UIImagePNGRepresentation(myImage);
    sqlite3_bind_blob(update_stmtement, 6, [imgData bytes], [imgData length], NULL);    
    }
    else {
        sqlite3_bind_blob(update_stmtement, 6, nil, -1, NULL);
    }

Чтение из SQLite DB:

NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(init_statement, 6) length:sqlite3_column_bytes(init_statement, 6)];
        if(data == nil)
            NSLog(@"No image found.");
        else
            self.pictureImage = [UIImage imageWithData:data];   

Ответ 5

Лучшей практикой является сжать изображение и сохранить его в базе данных или файловой системе. Если вы не заботитесь о разрешении изображения, вы можете пойти и даже изменить размер изображения, используя:

   UIGraphicsBeginImageContext(newSize);  
   [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];   
   UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();    
   UIGraphicsEndImageContext();

После этого вы можете использовать UIImageJPEGRepresentation для jpeg-изображений со значением "0" для максимального сжатия. Или вы можете использовать UIImagePNGRepresentation для png-изображений

Ответ 6

вы должны сначала написать изображение в файловой системе. а затем возьмите путь изображения и сохраните этот путь изображения (URL) как ТЕКСТ в sqlite.