ios 如何在核心数据中存储图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16685812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to store an image in core data
提问by Sipho Koza
I'm new to iOS. I've been trying to make an application that will store an image captured from the camera into CoreData
. I now know how to store data like NSString
s, NSDate
and other type but struggling to store an image. I've read so many articles saying you must write it to the disk and write to a file, but I can't seem to understand it.
我是 iOS 新手。我一直在尝试制作一个应用程序,它将从相机捕获的图像存储到CoreData
. 我现在知道如何存储像NSString
sNSDate
和其他类型的数据,但很难存储图像。我读了很多文章说必须将其写入磁盘并写入文件,但我似乎无法理解。
The following code is the one i used to store other data to core data.
以下代码是我用来将其他数据存储到核心数据的代码。
- (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];
}
回答by jansenmaarten
You can store images in Core Data using the Binary Data attribute type. However you should be aware of a few things:
您可以使用二进制数据属性类型将图像存储在 Core Data 中。但是,您应该注意以下几点:
Always convert your UIImage to a portable data format like png or jpg For example:
NSData *imageData = UIImagePNGRepresentation(image);
Enable "Allows external storage" on this attribute
Core Data will move the data to an external file if it hits a certain threshold. This file is also completely managed by Core Data, so you don't have to worry about it.
If you run into performance issues, try moving the Binary Data attribute to a separate entity.
You should abstract the conversion to NSData behind the interface of your NSManagedObject subclass, so you don't have to worry about conversions from UIImage to NSData or vice versa.
If your images are not strongly related to the entities in your model, I would suggest storing them outside of Core Data.
始终将您的 UIImage 转换为可移植的数据格式,例如 png 或 jpg 例如:
NSData *imageData = UIImagePNGRepresentation(image);
在此属性上启用“允许外部存储”,
如果达到某个阈值,Core Data 会将数据移动到外部文件。这个文件也完全由 Core Data 管理,所以你不必担心。
如果遇到性能问题,请尝试将 Binary Data 属性移至单独的实体。
您应该在 NSManagedObject 子类的接口后面抽象到 NSData 的转换,因此您不必担心从 UIImage 到 NSData 的转换,反之亦然。
如果您的图像与模型中的实体没有密切关系,我建议将它们存储在 Core Data 之外。
回答by Jemythehigh
In xcdatamodelId subclass declare image entity as NSData
... you can't use UIImage
format because image data is in binary format.
在 xcdatamodelId 子类中,将图像实体声明为NSData
...您不能使用UIImage
格式,因为图像数据是二进制格式。
@property (nonatomic, retain) NSData *imag;
In Implementation file.. convert UIImage
to NSData
在实现文件..转换UIImage
为NSData
UIImage *sampleimage = [UIImage imageNamed:@"sampleImage.jpg"];
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 0.0);
Then finally save it
然后最后保存
[obj setValue:dataImage forKey:@"imageEntity"]; // obj refers to NSManagedObject
回答by nomnom
For Swift 5and Swift 4.2
对于Swift 5和Swift 4.2
convert
UIImage
toData
:let imageData = image.jpegData(compressionQuality: 1.0)
save to
CoreData
:let object = MyEntity(context: managedContext) //create object of type MyEntity object.image = imageData //add image to object do { try managedContext.save() //save object to CoreData } catch let error as NSError { print("\(error), \(error.userInfo)") }
转换
UIImage
为Data
:let imageData = image.jpegData(compressionQuality: 1.0)
保存到
CoreData
:let object = MyEntity(context: managedContext) //create object of type MyEntity object.image = imageData //add image to object do { try managedContext.save() //save object to CoreData } catch let error as NSError { print("\(error), \(error.userInfo)") }
回答by Hermann Klecker
- (void)imageChanged:(UIImage*)image{
if (self.detailItem) {
[self.detailItem setValue:UIImagePNGRepresentation(image) forKey:kSignatureImage];
}
}
In this a very brief example. self
is a view controller using core data and self.detailItem is the usual NSManagedObject. In that project I did not create model classes for the entities but strictly use the KVC pattern to access the attributes. As you might guess, the attribute is named "signatureImage"
which I had defined in an #define constant kSignatureImage
.
这是一个非常简短的例子。self
是一个使用核心数据的视图控制器,self.detailItem 是通常的 NSManagedObject。在那个项目中,我没有为实体创建模型类,而是严格使用 KVC 模式来访问属性。正如您可能猜到的,该属性的名称"signatureImage"
是我在 #define 常量中定义的kSignatureImage
。
This is where the image is restored from core data:
这是从核心数据恢复图像的地方:
self.signatureCanvas.image = [UIImage imageWithData:[self.detailItem valueForKey:kSignatureImage]];
Again, self
is a view controller, signatureCanvas
is a UIImageView
subclass and .image
is its regular image
property inherited from UIImageView
. detailItem
, again, is the usual NSManagedObject
.
同样,self
是一个视图控制器,signatureCanvas
是一个UIImageView
子类,并且.image
是image
从UIImageView
. detailItem
,再次,是通常的NSManagedObject
。
The example is taken from a project I am currently working on.
该示例取自我目前正在进行的一个项目。
There are pros and cons for storing large data objects like images in core data or having them separated in files. Storing them in files means that you are responsible for deleting them when the related data objects are deleted. That provides coding overhead and may be volatile for programming errors. On the other hand, it may slow down the underlying database. I have not yet enough experience with this approach that I could share with respect to performance. In the end, the disk storage occupied is about the same size in total.
在核心数据中存储像图像这样的大型数据对象或将它们分开在文件中有利有弊。将它们存储在文件中意味着您有责任在删除相关数据对象时删除它们。这提供了编码开销并且对于编程错误可能是易失性的。另一方面,它可能会减慢底层数据库的速度。我对这种方法还没有足够的经验,我可以在性能方面分享。最终,占用的磁盘存储总量大致相同。
回答by Devang
Few links which might help you to get through this
很少有链接可以帮助您解决这个问题
https://stackoverflow.com/a/3909082/558000
https://stackoverflow.com/a/3909082/558000
Save and Retrieve of an UIImage on CoreData
回答by Utkarsh Jaiswal
It is possible to store images in Core Data as UIImage. Although this is not considered to be good practice as Databases are not meant for storing files. We don't use core data to store the images directly instead we use the file path to where the image data is stored on your phone.
可以将图像作为 UIImage 存储在 Core Data 中。尽管这不被认为是一种好的做法,因为数据库并不用于存储文件。我们不使用核心数据直接存储图像,而是使用文件路径到手机上存储图像数据的位置。
Anyways, the best method I found out while developing a side-project is demonstrated below
无论如何,我在开发副项目时发现的最佳方法如下所示
Select the attribute you want to be of Image type and choose transformableas it's type
Go to editor and select Create NSManagedObject Subclass
The Process will create 2 swift files depending on the number of your entities(I only had 1 entity). Now, select the
<EntityName> + CoreDataProperties.swift
file and import UIKit
选择您想要的图像类型的属性并选择可变形作为它的类型
转到编辑器并选择创建 NSManagedObject 子类
该流程将根据您的实体数量创建 2 个 swift 文件(我只有 1 个实体)。现在,选择
<EntityName> + CoreDataProperties.swift
文件并导入 UIKit
If, on clicking Jump to Definitionfor the @NSManaged public var UIImage definition
your work is done.
如果单击“跳转到定义”以查看 @NSManaged 公共变量,UIImage definition
您的工作就完成了。
Perform actions on the entities just like you would and you will be able to fetch, save, edit the image attribute by down-casting <EntityName>?.value(forKey: "<attributeName>") as? UIImage
.
像您一样对实体执行操作,您将能够通过向下转换来获取、保存和编辑图像属性<EntityName>?.value(forKey: "<attributeName>") as? UIImage
。
I had to use the entity as NSManagedObject
type and was for some reason not able to access the image directly from the created subclass.
我不得不使用实体作为NSManagedObject
类型,并且由于某种原因无法直接从创建的子类访问图像。
回答by Mangesh
I don't know why you want to store image in core data, while there is other persistent storage available in iOS. If you just want to store image for cache purpose, you can store it in document directory or cache directory. Happy Coding...
我不知道您为什么要将图像存储在核心数据中,而 iOS 中还有其他持久存储可用。如果您只想存储图像用于缓存目的,您可以将其存储在文档目录或缓存目录中。快乐编码...
Please refer below URL, How to store and retrieve images in document directory.
请参考以下 URL,如何在文档目录中存储和检索图像。
http://www.wmdeveloper.com/2010/09/save-and-load-uiimage-in-documents.html
http://www.wmdeveloper.com/2010/09/save-and-load-uiimage-in-documents.html
Saving image to Documents directory and retrieving for email attachment