我想保存 数据库中的图片,然后在数据库中获取图片。我转换 NSData 中的图片,图片是在数据库中成功存储,但是当我从数据库中获取该图像时,它会崩溃。发出此警告
警告: - [__ NSCFString bytes]:无法识别的选择器发送到实例0x7916000
代码下方用于在数据库中保存图像
NSData *dataImage1 = UIImagePNGRepresentation(image3.image);
NSString *str = [NSString stringWithFormat:@"Insert into Gallery(ImageName) VALUES ('%@')",dataImage1];
[Database executeQuery:str];
// Database.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);
先谢谢
答案 0 :(得分:2)
您的问题是您无法通过使用stringWithFormat
构建SQL语句来插入二进制数据。您正在将NSData
(二进制数据)插入名为ImageName
的字段中,并且不能使用stringWithFormat
来构建该SQL语句。
你真的想插入图像本身吗?在这种情况下,您可以使用下面的SQL,使用?
占位符,然后在调用1
之前使用sqlite3_bind_blob
将NSData
列号与sqlite3_step
一起使用}。因此,SQL看起来像:
Insert into Gallery(ImageName) VALUES (?)
(顺便说一下,我不喜欢选择ImageName
来获取图片的实际数据。我会使用Image
来获取实际的图片数据,或{{ 1}}用于图像的名称。)
然后,在准备好SQL之后,您将调用:
ImageName
然后,您可以像正常一样调用sqlite3_bind_blob(statement, 1, [dataImage1 bytes], [dataImage1 length], SQLITE_TRANSIENT);
来执行SQL以插入数据。
检索数据时,成功sqlite3_step
后,您将使用相应的sqlite3_step
函数:
sqlite3_column_blob
话说回来,SQLite在存储大型blob数据方面效率低下。您可能希望将图像存储在Documents文件夹中,然后将文件名存储在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];
字段中。
答案 1 :(得分:0)
我认为你在
中获取字符串类型的字节[[arra objectAtIndex:0] valueForKey:@"ImageName"];
首先获取字符串,然后将其转换为数据。
尝试这样:
NSData* data = [[[arra objectAtIndex:0] valueForKey:@"ImageName"] dataUsingEncoding:NSUTF8StringEncoding];