关于C#:读取图像并将图像写入SQLite DB以供iPhone使用

Reading and writing images to an SQLite DB for iPhone use

我已经建立了一个SQLite数据库,该数据库当前可以完美地读取和写入NSString。 我还想将图像存储在数据库中,然后再调用它。 我已经阅读了一些有关使用NSData并对图像进行编码的知识,但是我不确定要使用什么语法。 任何代码片段或示例将不胜感激。

我当前的过程是这样的:
UIImagePickerController->用户从照片中选择图像-> selectedImage设置为UIImageView的实例->现在,我要获取此图像并将其存储在数据库中

我应该提一下,此调用最终将被对远程服务器的调用所代替。 不确定这是否会影响性能。


您需要将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();

之后,您可以将UIImageJPEGRepresentation用于值为" 0"的jpeg图像进行最大压缩。或者您可以将UIImagePNGRepresentation用于png图像