Reading and writing images to an SQLite DB for iPhone use
我已经建立了一个SQLite数据库,该数据库当前可以完美地读取和写入
我当前的过程是这样的:
我应该提一下,此调用最终将被对远程服务器的调用所代替。 不确定这是否会影响性能。
您需要将UIImageView中托管的UIImage转换为二进制BLOB,以存储在SQLite中。为此,可以使用以下命令:
1 2 | NSData *dataForImage = UIImagePNGRepresentation(cachedImage); sqlite3_bind_blob(yourSavingSQLStatement, 2, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT); |
这将生成图像的PNG表示形式,将其存储在NSData实例中,然后将来自NSData的字节作为BLOB绑定为SQL查询中第二个参数。如果愿意,可以使用上面的UIImageJPEGRepresentation以该格式存储。您需要将BLOB列添加到SQLite数据库中的相应表中。
要检索此图像,可以使用以下方法:
1 2 3 | NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)]; self.cachedImage = [UIImage imageWithData:dataForCachedImage]; [dataForCachedImage release]; |
苹果的建议是不要将BLOB存储在大于2 KB的SQLite数据库中。
SQLite将数据库组织到页面中。每个页面的大小为4 KB。当您从SQLite数据库文件读取数据时,它将这些页面加载到内部页面缓存中。在iPhone上,我认为此缓存的默认大小为1 MB。这使得读取相邻记录非常快,因为它们可能已经在页面缓存中了。
当SQLite将您的数据库记录读入内存时,它将读取整个记录及其占用的所有页面。因此,如果您的记录包含BLOB,则它可能会占用许多页面,并且您将从缓存中弹出现有页面,并用BLOB记录的页面替换它们。
如果您只是扫描并加载所有BLOBS以便对它们进行某些操作(例如显示它们),这还不错。但是,如果说您在一个查询中只想获取与BLOB在同一行中的数据,则该查询将比记录中不包含大BLOB的查询慢很多。
因此,至少应将BLOB数据存储在单独的表中。例如:
1 2 3 | 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)。
一种选择(当使用SQL时通常是首选)是将映像写入系统上的文件,并将路径(或其他某种标识符)存储在数据库中。
将图像写入SQLite DB
1 2 3 4 5 6 7 | 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读取:
1 2 3 4 5 | 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]; |
您应该首先在文件系统上写入映像。然后获取图像路径并将该图像路径(URL)作为文本存储在sqlite中。
最佳实践是压缩映像并将其存储在数据库或文件系统中。如果您不关心图像的分辨率,则可以使用以下方法进行操作,甚至调整图像的大小:
1 2 3 4 | UIGraphicsBeginImageContext(newSize); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); |
之后,您可以将