选择后图像不会显示在图像视图中

发布于 2024-12-11 03:48:41 字数 574 浏览 0 评论 0原文

我正在尝试将图像保存在核心数据中,但是在模拟器中选择它后,它没有显示在图像视图中?这是代码示例:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if (fugitive_.image != nil) {
        self.fugitiveImage.image = [UIImage imageWithData:fugitive_.image];
    }
}

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
   fugitive.image = UIImagePNGRepresentation([info objectForKey:UIImagePickerControllerEditedImage]);
    [self dismissModalViewControllerAnimated:YES];
    [picker release];
}

I am trying to save an image in core data but after I select it in the simulator, it doesn't show up in the image view? Here is a sample of the code:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if (fugitive_.image != nil) {
        self.fugitiveImage.image = [UIImage imageWithData:fugitive_.image];
    }
}

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
   fugitive.image = UIImagePNGRepresentation([info objectForKey:UIImagePickerControllerEditedImage]);
    [self dismissModalViewControllerAnimated:YES];
    [picker release];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最美不过初阳 2024-12-18 03:48:41

首先,不要在 Core Data 中存储图像(或任何二进制数据);特别是在 iOS 上。将其存储在磁盘上,然后存储对 Core Data 中文件位置的引用,您将获得更好的性能。

其次,您的示例代码没有显示您如何将数据放入核心数据中。因此很难提出解决方案。

更新

我没有找到如何执行此操作的简单参考,因此这里有一个:

iOS 5.0 之前的图像缓存

要在 iOS 5.0 之前的环境中在磁盘上设置图像缓存,您需要首先在实体上创建一个属性,即一个 NSString。在此示例中,我们将该属性命名为 imageFilename。完成后,我们将希望为我们的实体创建一个 NSManagedObject 子类,以便我们可以实现辅助方法:

@interface MyEntity : NSManagedObject

@property (nonatomic, retain) NSString *imageFilename;
@property (nonatomic, retain) NSImage *image;

@end

我们将让 Core Data 管理 imageFilename 因为它是在模型中定义的。然而,我们将实现image的访问器。

@implementation MyEntity

@dynamic imageFilename;

@synthesize image = _image;

- (void)setImage:(UIImage*)image
{
    NSString *filename = [self imageFilename];
    if (!filename) {
        filename = [[NSProcessInfo processInfo] globallyUniqueString];
        [self setImageFilename:filename];
    }

    [_image release];
    _image = [image retain];

    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
    NSData *data = UIImagePNGRepresentation(image);

    NSError *error = nil;
    if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) {
        NSLog(@"Failed to write image to disk: %@\n%@", [error localizedDescription], [error userInfo]);
        return;
    }
}

-setImage: 会将图像保存到磁盘的缓存目录中(请注意,缓存目录不会备份,在空间不足的情况下可以被系统删除)。如果尚未创建文件名,它将选择一个随机文件名。

故意不存储路径,因为应用程序沙箱的目录可能会更改。因此我们只想将文件名存储在 Core Data 中并解析路径。

我们还在内存中保留对图像的引用,以便在该实体的生命周期期间再次请求该图像时,我们不会访问磁盘。这就是 @synthesize 的原因,即使我们正在实现访问器。

请注意,我们将图像以 PNG 格式存储在磁盘上。这可能很昂贵(压缩例程相对较慢),但它使图像保持通用格式,这可能很有用。

- (UIImage*)image
{
    if (_image) return _image;
    NSString *filename = [self imageFilename];
    if (!filename) return nil;
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];

    if (![[NSFileManager defaultFileManager] fileExistsAtPath:filePath]) return nil;

    _image = [[UIImage alloc] initWithContentsOfFile:filePath];
    return _image;
}

-image 的实现几乎相反。我们检查是否有文件名;解析完整路径并将图像加载到内存中,然后将其返回给调用者。

- (void)prepareForDeletion
{
    [super prepareForDeletion];

    NSString *filename = [self imageFilename];
    if (!filename) return nil;
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];

    NSError *error = nil;
    if (![[NSFileManager defaultFileManager] removeItemAtPath:filePath error:&error]) {
        NSLog(@"Potential error removing on disk image: %@\n%@", [error localizedDescription], [error userInfo]);
    }
}

我们希望保持缓存目录尽可能干净,这样就不会造成空间不足的情况。因此,当要从核心数据中删除实体时,我们希望从磁盘中删除该文件。删除期间发生的实际错误对我们来说并不是致命的问题。这可能是一个错误,因为该文件已被删除或其他原因。没有理由因为此错误而完全失败,但记录它很重要。

- (void)willTurnIntoFault
{
    [super willTurnIntoFault];
    [_image release], _image = nil;
}

@end

最后,我们实现 -willTurnIntoFault 方法,以便我们可以在实体生命周期结束时释放内存中对该图像的引用。

图像缓存 iOS 5.0+

  1. 在实体上创建二进制属性。
  2. 打开“存储在外部记录文件中”位。
  3. 没有第三步

First, do not store images (or any binary data) in Core Data; especially on iOS. You will get far better performance storing it on disk and then storing a reference to the file location in Core Data.

Second, your sample code does not show how you are putting the data into Core Data. Therefore it is hard to suggest a solution.

Update

I did not find a simple reference to how to do this so here is one:

Image Cache Pre iOS 5.0

To set up an image cache on disk in a pre-iOS 5.0 environment you want to first create an attribute on your entity that is a NSString. In this example we will name that attribute imageFilename. Once that is complete we will want to create a subclass of NSManagedObject for our entity so that we can implement the helper methods:

@interface MyEntity : NSManagedObject

@property (nonatomic, retain) NSString *imageFilename;
@property (nonatomic, retain) NSImage *image;

@end

We are going to let Core Data manage the imageFilename since it is defined in the model. However we are going to implement the accessors for image.

@implementation MyEntity

@dynamic imageFilename;

@synthesize image = _image;

- (void)setImage:(UIImage*)image
{
    NSString *filename = [self imageFilename];
    if (!filename) {
        filename = [[NSProcessInfo processInfo] globallyUniqueString];
        [self setImageFilename:filename];
    }

    [_image release];
    _image = [image retain];

    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];
    NSData *data = UIImagePNGRepresentation(image);

    NSError *error = nil;
    if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) {
        NSLog(@"Failed to write image to disk: %@\n%@", [error localizedDescription], [error userInfo]);
        return;
    }
}

The -setImage: will save the image to disk into the cache directory (note that the cache directory is not backed up and can be delete by the system in the event of a low space situation). It selects a random filename if one has not been created already.

The path is intentionally not stored because the directory of the application's sandbox can change. Therefore we only want to store the filename in Core Data and resolve the path.

We also keep an in memory reference to the image so that we are not hitting disk if the image is asked for again during this entity's lifecycle. This is the reason for the @synthesize even though we are implementing the accessors.

Note that we store the images on disk as PNG. This can be expensive (the compression routines are relatively slow) but it keeps the image in a universal format which can be useful.

- (UIImage*)image
{
    if (_image) return _image;
    NSString *filename = [self imageFilename];
    if (!filename) return nil;
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];

    if (![[NSFileManager defaultFileManager] fileExistsAtPath:filePath]) return nil;

    _image = [[UIImage alloc] initWithContentsOfFile:filePath];
    return _image;
}

The implementation of the -image is pretty much the reverse. We check to see if we have a filename; resolve the full path and load the image into memory and then return it to the caller.

- (void)prepareForDeletion
{
    [super prepareForDeletion];

    NSString *filename = [self imageFilename];
    if (!filename) return nil;
    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [cachePath stringByAppendingPathComponent:filename];

    NSError *error = nil;
    if (![[NSFileManager defaultFileManager] removeItemAtPath:filePath error:&error]) {
        NSLog(@"Potential error removing on disk image: %@\n%@", [error localizedDescription], [error userInfo]);
    }
}

We want to keep our cache directory as clean as possible so that we do not create a low space situation. Therefore when the entity is going to be deleted from Core Data we want to remove the file from disk. The actual error that happens during a delete is a non-fatal issue for us. It could be an error because the file was already deleted or something else. There is no reason to completely fail for this error but it is important to log it.

- (void)willTurnIntoFault
{
    [super willTurnIntoFault];
    [_image release], _image = nil;
}

@end

Finally, we implement the -willTurnIntoFault method so that we can release our in-memory reference to the image at the end of this entity's lifecycle.

Image Cache iOS 5.0+

  1. Create a binary attribute on the entity.
  2. Turn on the "Store in External Record File" bit.
  3. There is no step three
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文