如何在核心数据中存储图像

我是iOS新手。 我一直在试图制作一个应用程序,将相机捕获的图像存储到CoreData 。 我现在知道如何存储像NSString s, NSDate和其他types的数据,但努力存储图像。 我已经阅读了很多文章,说你必须把它写入磁盘并写入一个文件,但我似乎无法理解它。

以下代码是我用来将其他数据存储到核心数据的代码。

 - (IBAction)submitReportButton:(id)sender { UrbanRangerAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; managedObjectContext = [appDelegate managedObjectContext]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"PotholesDB" inManagedObjectContext:appDelegate.managedObjectContext]; NSManagedObject *newPothole = [[NSManagedObject alloc]initWithEntity:entity insertIntoManagedObjectContext:managedObjectContext]; [newPothole setValue:self.relevantBody.text forKey:@"relevantBody"]; [newPothole setValue:self.subjectReport.text forKey:@"subjectReport"]; [newPothole setValue:self.detailReport.text forKey:@"detailReport"]; // [newPothole setValue:self.imageView forKey:@"photo"]; NSDate *now = [NSDate date]; //NSLog(@"now : %@", now); NSString *strDate = [[NSString alloc] initWithFormat:@"%@", now]; NSArray *arr = [strDate componentsSeparatedByString:@" "]; NSString *str; str = [arr objectAtIndex:0]; NSLog(@"now : %@", str); [newPothole setValue:now forKey:@"photoDate"]; [newPothole setValue:self.latitudeLabel.text forKey:@"latitude"]; [newPothole setValue:self.longitudeLabel.text forKey:@"longitude"]; [newPothole setValue:self.addressLabel.text forKey:@"streetName"]; [newPothole setValue:streeNameLocation forKey:@"location"]; NSError *error; [managedObjectContext save:&error]; UIAlertView *ll = [[UIAlertView alloc] initWithTitle:@"Saving" message:@"Saved data" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [ll show]; } 

您可以使用二进制数据属性types将图像存储在核心数据中。 不过,你应该知道一些事情:

  • 总是将您的UIImage转换为像png或jpg这样的便携式数据格式。例如:

    NSData *imageData = UIImagePNGRepresentation(image);

  • 在此属性上启用“允许外部存储” 描述 如果数据达到一定的阈值,核心数据将把数据移动到外部文件。 这个文件也完全由Core Datapipe理,所以你不必担心。

  • 如果遇到性能问题,请尝试将“二进制数据”属性移至单独的实体。

  • 你应该在NSManagedObject子类的接口后面抽象转换到NSData,所以你不必担心从UIImage到NSData的转换,反之亦然。

  • 如果你的图像与模型中的实体没有强相关,我build议将它们存储在核心数据之外。

在xcdatamodelId子类中将图像实体声明为NSData …因为图像数据是二进制格式,所以不能使用UIImage格式。

 @property (nonatomic, retain) NSData *imag; 

在实现文件中..将UIImage转换为NSData

 UIImage *sampleimage = [UIImage imageNamed:@"sampleImage.jpg"]; NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 0.0); 

然后最后保存它

 [obj setValue:dataImage forKey:@"imageEntity"]; // obj refers to NSManagedObject 
 - (void)imageChanged:(UIImage*)image{ if (self.detailItem) { [self.detailItem setValue:UIImagePNGRepresentation(image) forKey:kSignatureImage]; } } 

在这个非常简短的例子。 self是使用核心数据的视图控制器,self.detailItem是通常的NSManagedObject。 在那个项目中,我没有为实体创build模型类,而是严格使用KVC模式来访问属性。 正如你可能猜到的那样,这个属性被命名为"signatureImage" ,这是我在#define常量kSignatureImage定义的。

这是从核心数据恢复映像的地方:

 self.signatureCanvas.image = [UIImage imageWithData:[self.detailItem valueForKey:kSignatureImage]]; 

再次, self是一个视图控制器, signatureCanvas是一个UIImageView子类,而.image是它从UIImageViewinheritance的常规image属性。 detailItem也是通常的NSManagedObject

这个例子来自于我目前正在进行的一个项目。

在核心数据中存储像图像这样的大型数据对象或将它们分隔在文件中有利有弊。 将它们存储在文件中意味着删除相关数据对象时,您有责任删除它们。 这提供了编码开销并且对于编程错误可能是易失的。 另一方面,这可能会降低底层数据库的速度。 我还没有足够的经验可以分享我的performance。 最后,占用的磁盘存储量总共大约相同。

几个链接,可能会帮助你通过这个

https://stackoverflow.com/a/3909082/558000

保存并检索CoreData上的UIImage

http://ootips.org/yonat/uiimage-in-coredata/

我不知道你为什么要将图像存储在核心数据中,而iOS中还有其他持久性存储。 如果您只是为了caching目的而存储图像,则可以将其存储在文档目录或caching目录中。 快乐编码

请参阅下面的URL,如何在文档目录中存储和检索图像。

http://www.wmdeveloper.com/2010/09/save-and-load-uiimage-in-documents.html

将图像保存到文档目录并检索电子邮件附件

如何用Cocoa创build一个临时文件?