Lecture et écriture des images à une base de données SQLite pour iPhone

voix
22

J'ai mis en place un DB SQLite qui lit et écrit actuellement NSStringest tout à fait. Je veux aussi stocker une image dans la base de données et rappeler ultérieurement. J'ai lu un peu sur l' utilisation NSDataet le codage de l'image, mais je ne suis pas tout à fait sûr de ce que la syntaxe est ce que je veux faire. Tous les extraits de code ou des exemples seraient grandement appréciés.

Mon processus actuel se présente comme suit: UIImagePickerController-> Image de l' utilisateur Choisit Photos -> chosenImage est réglé sur instance de UIImageView-> Maintenant , je veux profiter de cette image et le stocker dans le DB

Je dois mentionner cet appel sera éventuellement remplacé par un appel à un serveur distant. Je ne sais pas si cela fait une différence dans la mesure du rendement va.

Créé 13/03/2009 à 18:03
source utilisateur
Dans d'autres langues...                            


6 réponses

voix
31

Vous aurez besoin de convertir le UIImage hébergé au sein de votre UIImageView dans un blob binaire pour le stockage dans SQLite. Pour ce faire, vous pouvez utiliser les éléments suivants:

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

Cela va générer une représentation PNG de l'image, le stocker dans une instance NSData, puis lier les octets du NSData comme blob pour le second argument dans votre requête SQL. Utilisez UIImageJPEGRepresentation dans le ci-dessus pour stocker dans ce format, si vous le souhaitez. Vous aurez besoin d'avoir une colonne de type BLOB ajoutée à la table appropriée dans votre base de données SQLite.

Pour récupérer cette image, vous pouvez utiliser les éléments suivants:

NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)];       
self.cachedImage = [UIImage imageWithData:dataForCachedImage];
[dataForCachedImage release];
Créé 13/03/2009 à 18:41
source utilisateur

voix
9

la recommandation d'Apple est de ne pas stocker blob de bases de données SQLite qui sont plus grandes que ~ 2 kilo-octets.

SQLite organise des bases de données dans les pages. Chaque page est de 4 kilo-octets en taille. Lorsque vous lisez des données à partir du fichier de base de données SQLite il charge ces pages dans un cache de page interne. Sur l'iPhone, je pense que ce défaut de cache à 1 méga-octet en taille. Cela rend la lecture des enregistrements adjacents très vite, car ils seront probablement dans le cache de page déjà.

Lorsque SQLite lit votre dossier de base de données en mémoire, il lit l'enregistrement et toutes les pages qu'il occupe. Donc, si votre dossier contient un blob, il pourrait occuper plusieurs pages et vous serez éjecter les pages existantes du cache et de les remplacer par les pages de votre dossier blob.

Ce n'est pas si mal si vous êtes juste à travers la numérisation et le chargement tout votre BLOBS faire quelque chose avec eux (les afficher par exemple). Mais si vous avez fait dire une requête où vous vouliez juste pour obtenir des données qui sont dans la même ligne que le blob cette requête serait beaucoup plus lent que si le dossier ne contenait pas le grand blob.

Donc, au minimum, vous devez stocker vos données BLOB dans un tableau distinct. Par exemple:

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

Ou mieux encore, stocker les données BLOB sous forme de fichiers en dehors de la base de données SQLite.

Notez qu'il est possible de modifier la taille du cache de page avec des instructions SQL PRAGMA (si vous ne l' utilisez CoreData).

Créé 15/04/2011 à 11:21
source utilisateur

voix
9

L'une des options (et généralement lorsque vous travaillez dans SQL) est d'écrire l'image dans un fichier sur le système et stocker le chemin (ou un autre type d'identifiant) dans la base de données.

Créé 13/03/2009 à 18:32
source utilisateur

voix
2

Ecriture d'une image 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);
    }

De la lecture 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];   
Créé 29/01/2010 à 14:05
source utilisateur

voix
0

vous devez d'abord écrire l'image sur le système de fichiers. puis prendre le chemin de l'image et de stocker ce chemin d'image (URL) sous forme de texte SQLite.

Créé 27/05/2015 à 07:08
source utilisateur

voix
0

La meilleure pratique consiste à compresser l'image et le stocker dans la base de données ou un système de fichiers. Si vous ne se soucient pas de la résolution de l'image que vous pouvez aller de l'avant et même redimensionner l'image en utilisant:

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

Après cela , vous pouvez utiliser UIImageJPEGRepresentationpour des images jpeg avec une valeur de « 0 » pour une compression maximale. Ou vous pouvez utiliser UIImagePNGRepresentationpour des images .png

Créé 05/07/2012 à 13:21
source utilisateur

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