it-swarm.com.ru

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

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

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

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

22
Jeff

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

9
Lounges

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

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

Это сгенерирует PNG-представление вашего изображения, сохранит его в экземпляре NSData, а затем свяжет байты из NSData как BLOB для второго аргумента в вашем запросе SQL. Используйте UIImageJPEGRepresentation в приведенном выше, чтобы сохранить в этом формате, если хотите. Вам нужно будет добавить столбец 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];
31
Brad Larson

Apple не рекомендует хранить BLOB в базах данных SQLite, размер которых превышает ~ 2 килобайта.

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

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

Это не так уж плохо, если вы просто просматриваете и загружаете все свои BLOB-объекты, чтобы что-то с ними сделать (например, отобразите их). Но если, скажем, вы сделали запрос, в котором вы просто хотели получить некоторые данные, которые находятся в той же строке, что и 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).

9
orj

Запись изображения в БД SQLite

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:

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];   
2
Xorsat

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

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

После этого вы можете использовать UIImageJPEGRepresentation для изображений JPEG со значением «0» для максимального сжатия. Или вы можете использовать UIImagePNGRepresentation для изображений PNG

0
Kiran Kulkarni

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

0
Siddhesh Mahadeshwar