Lectura y escritura de imágenes en un SQLite DB para uso de iPhone

votos
22

Configuré una base de datos SQLite que actualmente lee y escribe NSStringperfectamente. También quiero almacenar una imagen en la base de datos y recuperarla más tarde. He leído un poco sobre el uso NSDatay la codificación de la imagen, pero no estoy del todo seguro de cuál es la sintaxis para lo que quiero hacer. Cualquier fragmento de código o ejemplo sería muy apreciado.

Mi proceso actual es el siguiente: UIImagePickerController-> El usuario elige la imagen de las fotos -> elegida La imagen está configurada como instancia de UIImageView-> Ahora quiero tomar esta imagen y almacenarla en la base de datos

Debo mencionar que esta llamada será reemplazada con una llamada a un servidor remoto. No estoy seguro de si esto hace una diferencia en lo que respecta al rendimiento.

Publicado el 13/03/2009 a las 18:03
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
31

Tendrá que convertir el UIImage alojado en su UIImageView en un BLOB binario para el almacenamiento en SQLite. Para hacer eso, puede usar lo siguiente:

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

Esto generará una representación PNG de su imagen, la almacenará en una instancia de NSData y luego vinculará los bytes de NSData como un BLOB para el segundo argumento en su consulta SQL. Utilice UIImageJPEGRepresentation en lo anterior para almacenar en ese formato, si lo desea. Tendrá que tener una columna BLOB agregada a la tabla apropiada en su base de datos SQLite.

Para recuperar esta imagen, puede usar lo siguiente:

NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)];       
self.cachedImage = [UIImage imageWithData:dataForCachedImage];
[dataForCachedImage release];
Respondida el 13/03/2009 a las 18:41
fuente por usuario

votos
9

la recomendación de Apple es no almacenar BLOB de bases de datos SQLite en que son más grandes de lo ~ 2 kilobytes.

SQLite organiza las bases de datos en páginas. Cada página es de 4 kilobytes de tamaño. Cuando uno lee los datos desde el archivo de base de datos SQLite se carga estas páginas en una memoria caché de páginas internas. En el iPhone Creo que esta caché por defecto a 1 megabyte de tamaño. Esto hace que la lectura de los registros adyacentes muy rápido, ya que probablemente estarán en la caché de páginas ya.

Cuando SQLite lee su registro de base de datos en la memoria se lee el registro completo y todas las páginas que ocupa. Así que si su registro contiene un BLOB, podría ocupar muchas páginas y se le expulsa las páginas existentes de la memoria caché y su sustitución por las páginas de su récord BLOB.

Esto no es tan malo si sólo está escaneando a través y cargar todos sus gotas para hacer algo con ellos (los muestra por ejemplo). Pero si decir que hizo una consulta en la que sólo quería conseguir algunos datos que se encuentra en la misma fila que el BLOB esta consulta sería mucho más lento que si el expediente no contiene la gran BLOB.

Así que, como mínimo, debe almacenar sus datos BLOB en una tabla separada. P.ej:

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) );

O mejor aún, almacenar los datos BLOB como archivos fuera de la base de datos SQLite.

Tenga en cuenta que puede ser posible ajustar el tamaño de caché de páginas con declaraciones SQL PRAGMA (si no se está usando CoreData).

Respondida el 15/04/2011 a las 11:21
fuente por usuario

votos
9

Una opción (y generalmente preferida cuando se trabaja en SQL) es escribir la imagen en un archivo en el sistema y almacenar la ruta (o algún otro tipo de identificador) en la base de datos.

Respondida el 13/03/2009 a las 18:32
fuente por usuario

votos
2

Escritura de la imagen a 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);
    }

A partir de la lectura de 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];   
Respondida el 29/01/2010 a las 14:05
fuente por usuario

votos
0

primero debe escribir una imagen del sistema de archivos. y luego tomar la ruta de la imagen y almacenar esa ruta de la imagen (URL) como texto en SQLite.

Respondida el 27/05/2015 a las 07:08
fuente por usuario

votos
0

La mejor práctica es comprimir la imagen y almacenarla en el sistema de base de datos o archivo. Si no se preocupan por la resolución de la imagen que puede seguir adelante e incluso cambiar el tamaño de la imagen mediante el uso de:

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

Después de que se puede utilizar UIImageJPEGRepresentationpara las imágenes JPEG con un valor de "0" para la compresión máxima. O puede utilizar UIImagePNGRepresentationpara imágenes PNG

Respondida el 05/07/2012 a las 13:21
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more