Lese og skrive bilder til en SQLite DB for iPhone bruk

stemmer
22

Jeg har satt opp en SQLite DB som i dag leser og skriver NSStringer perfekt. Jeg ønsker også å lagre et bilde i databasen og hente den senere. Jeg har lest opp litt om bruk NSDataog koding av bildet, men jeg er ikke helt sikker på hva syntaksen er for hva jeg vil gjøre. Eventuelle kodebiter eller eksempler vil bli verdsatt.

Min nåværende prosessen går slik: UIImagePickerController-> Bruker Velger Bilde fra bilder -> chosenImage er satt til forekomst av UIImageView-> Nå ønsker jeg å ta dette bildet og lagre den i DB

Jeg bør nevne denne samtalen vil etterhvert bli erstattet med en oppfordring til en ekstern server. Ikke sikker på om dette gjør en forskjell når det gjelder ytelse går.

Publisert på 13/03/2009 klokken 17:03
kilden bruker
På andre språk...                            


6 svar

stemmer
31

Du må konvertere UIImage vert innenfor UIImageView inn en binær BLOB for lagring i SQLite. For å gjøre det, kan du bruke følgende:

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

Dette vil generere en PNG representasjon av bildet, lagre den i en NSData eksempel, og deretter binde den bytes fra NSData som en BLOB for den andre argumentet i SQL-spørring. Bruk UIImageJPEGRepresentation i ovennevnte å lagre i dette formatet, om du vil. Du må ha en BLOB kolonne lagt til den aktuelle tabellen i SQLite database.

For å hente dette bildet, kan du bruke følgende:

NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)];       
self.cachedImage = [UIImage imageWithData:dataForCachedImage];
[dataForCachedImage release];
Svarte 13/03/2009 kl. 17:41
kilden bruker

stemmer
9

Apples anbefaling er å ikke lagre BLOB er i SQLite databaser som er større enn ~ 2 kilobyte.

SQLite organiserer databaser i sidene. Hver side er 4 kilobyte i størrelse. Når du leser data fra SQLite databasefilen den laster disse sidene i en intern side cache. På iPhone jeg tror dette cache som standard en megabyte i størrelse. Dette gjør lesing tilstøtende poster veldig fort fordi de vil trolig være på siden cache allerede.

Når SQLite leser database rekord i minnet leser hele posten og alle sidene som det står på. Så hvis posten inneholder en BLOB, kan det opptar mange sider, og du vil bli med å mate ut eksisterende sider fra cache og erstatte dem med BLOB rekord sider.

Dette er ikke så ille hvis du bare skanne gjennom og laste alle blobs å gjøre noe med dem (vise dem for eksempel). Men hvis si du gjorde et søk der du bare ønsket å få noen data som er i samme rad som BLOB dette søket ville være mye tregere enn hvis posten ikke inneholder store BLOB.

Så på et minimum bør du lagre dine BLOB data i en egen tabell. Eg:

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

Eller enda bedre, lagre BLOB data som filer utenfor SQLite database.

Merk at det kan være mulig å justere siden bufferstørrelsen med SQL Pragma uttalelser (hvis du ikke bruker CoreData).

Svarte 15/04/2011 kl. 10:21
kilden bruker

stemmer
9

Ett alternativ (og generelt foretrukket når du arbeider i SQL) er å skrive bildet til en fil på systemet og lagre banen (eller en annen form for ID) i databasen.

Svarte 13/03/2009 kl. 17:32
kilden bruker

stemmer
2

Skriving på bildet for å 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);
    }

Lese Fra 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];   
Svarte 29/01/2010 kl. 13:05
kilden bruker

stemmer
0

bør du først skrive bildet på filsystemet. og deretter ta bilde banen og lagre det bildet banen (URL) som tekst i SQLite.

Svarte 27/05/2015 kl. 07:08
kilden bruker

stemmer
0

Den beste praksis er å komprimere bildet og lagre den i databasen eller filsystemet. Hvis du ikke bryr seg om oppløsningen i bildet kan du gå videre og selv endre størrelsen på bildet ved å bruke:

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

Etter det kan du bruke UIImageJPEGRepresentationfor JPEG-bilder med en verdi på "0" for maksimal komprimering. Eller du kan bruke UIImagePNGRepresentationfor PNG-bilder

Svarte 05/07/2012 kl. 12:21
kilden bruker

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