2

我想将图像保存在数据库中并在数据库中获取图像。我在NSData中转换图像并且图像已成功存储在数据库中但是当我从数据库中获取该图像时它会崩溃。它会给出这个警告

警告:- - [__NSCFString bytes]:无法识别的选择器发送到实例 0x7916000

下面的代码用于将图像保存在数据库中

NSData *dataImage1 = UIImagePNGRepresentation(image3.image);
 NSString   *str = [NSString stringWithFormat:@"Insert into Gallery(ImageName) VALUES ('%@')",dataImage1];
[Database executeQuery:str];

//数据库.m

+(NSString* )getDatabasePath{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Database"];
    return writableDBPath;

}

+(NSMutableArray *)executeQuery:(NSString*)str{

    sqlite3_stmt *statement= nil;
    sqlite3 *database;
    NSString *strPath = [self getDatabasePath];
    NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
    if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
        if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {


            while (sqlite3_step(statement) == SQLITE_ROW) {
                            NSInteger i = 0;
                NSInteger iColumnCount = sqlite3_column_count(statement);
                NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
                while (i< iColumnCount) {
                    NSString *str = [self encodedString:(const unsigned char*)sqlite3_column_text(statement, i)];


                NSString *strFieldName = [self encodedString:(const unsigned char*)sqlite3_column_name(statement, i)];

                    [dict setObject:str forKey:strFieldName];
                    i++;
                }

                [allDataArray addObject:dict];
                [dict release];
            }
        }

        sqlite3_finalize(statement);
    } 
    sqlite3_close(database);
    return allDataArray;
}

//获取图片

NSString *str =[NSString stringWithFormat:@"Select * from Gallery where id = 1"];
NSMutableArray *arra =[Database executeQuery:str];
NSData *d =[[arra objectAtIndex:0] valueForKey:@"ImageName"];
UIImage *img = [[UIImage alloc] initWithData:d];
NSLog(@"%@",img);

提前致谢

4

2 回答 2

2

您的问题是您无法通过使用stringWithFormat. 您将NSData(二进制数据)插入到名为 的字段中ImageName,并且不能用于stringWithFormat构建该 SQL 语句。

您真的是要插入图像本身吗?在这种情况下,您将使用如下所示的 SQL 和占位符,?然后在调用. 因此,SQL 看起来像:sqlite3_bind_blob1NSDatasqlite3_step

Insert into Gallery(ImageName) VALUES (?)

(顺便说一句,我不喜欢选择ImageName图像的实际数据。我要么Image用于实际的图像数据,要么ImageName用于图像的名称。)

然后,在准备好 SQL 之后,您将调用:

sqlite3_bind_blob(statement, 1, [dataImage1 bytes], [dataImage1 length], SQLITE_TRANSIENT);

然后,您可以sqlite3_step像往常一样调用 来执行 SQL 以插入数据。

检索数据时,成功后sqlite3_step,您将使用适当的sqlite3_column_blob功能:

const void *bytes = sqlite3_column_blob(statement, 0);
int len = sqlite3_column_bytes(statement, 0);
NSData *data = [NSData dataWithBytes:bytes length:len];
UIImage *image = [UIImage imageWithData:data];

话虽如此,SQLite 在存储大型 blob 数据方面是出了名的低效。您可能希望将图像存储在 Documents 文件夹中,然后将文件名存储在您的ImageName字段中。

于 2013-08-01T12:38:51.373 回答
0

我认为您正在获取字符串类型的字节

[[arra objectAtIndex:0] valueForKey:@"ImageName"];

所以首先获取字符串,然后将其转换为数据。

试试这样:

NSData* data = [[[arra objectAtIndex:0] valueForKey:@"ImageName"] dataUsingEncoding:NSUTF8StringEncoding];
于 2013-08-01T12:31:49.843 回答