Re: Core Data Binding: Reading a binary image (TIFF)
Re: Core Data Binding: Reading a binary image (TIFF)
- Subject: Re: Core Data Binding: Reading a binary image (TIFF)
- From: Jeff LaMarche <email@hidden>
- Date: Tue, 3 Jan 2006 21:14:15 -0500
On Jan 3, 2006, at 8:33 PM, Frederick C. Lee wrote:
I've encoded a NSImage to NSData object via the following:
NSData *encodedMap = [[gvNewMapView image] TIFFRepresentation];
I would think your best bet would be to keep you binary attribute as
is, and create a transient undefined attribute for the NSImage. You
could avoid any re-compression and could just treat your entity as if
it had an NSImage attribute. You could do something like this
(assuming imageData is the name of your binary attribute and image is
the name of you undefined transient attribute (this is typed in e-
mail, so usually warnings and disclaimers):
First, you need to create a custom subclass of NSManagedObject for
your class. There's a file template just for doing this that will do
most of the work for you. You need to create a fairly normal looking
mutator for the transient attribute. While your program is running,
Core Data will maintain the state for your transient attribute, so
Xcode's designer will create this one for you and you shouldn't need
to change it except to specify the object type for its parameter:
- (void)setImage:(NSImage *)inImage
{
[self willChangeValueForKey: @"image"];
[self setPrimitiveValue:[value copy] forKey: @"image"];
[self didChangeValueForKey: @"image"];
}
then, just before a save, you need to archive the image into your
concrete binary attribute.
- (void)willSave
{
NSImage *tmpImage = [self primitiveValueForKey:@"image"];
if (array != nil)
{
[self setPrimitiveValue:[NSArchiver tmpImage]
forKey:@"imageData"];
}
else
[self setPrimitiveValue:nil forKey:@"imageData"];
[super willSave];
}
On the other side of the equation, you need to create an accessor,
and like the mutator, this will look fairly normal, since all the
state is managed exactly like concrete attributes during your
application's lifespan. Again, if you use the Designer, it will
create this method for you, and you just need to change the type of
the object that gets returned and the variable that holds it:
- (NSImage *)image
{
NSImage *ret;
[self willAccessValueForKey: @"image"];
ret = [self primitiveValueForKey: @"image"];
[self didAccessValueForKey: @"image"];
return ret;
}
Finally, when your data is loaded at launch time, you need to create
the image from the binary data:
- (void)awakeFromFetch
{
NSData *imageData = [self valueForKey:@"imageData"];
if (imageData != nil)
{
NSImage *image = [NSUnarchiver
unarchiveObjectWithData:imageData];
[self setPrimitiveValue:array forKey:@"image"];
}
}
Then that's it - once you do this, you can just access the image
attribute as an NSImage, and treate it just as if it were another
concrete attribute. You don't have to worry about any kind of
encoding or compression or anything until such time that you need to
export the data somewhere else or otherwise do something with it. One
thing, though - if you do this, you should ONLY use the transient
attribute's accessor and mutator to make sure everything stays in
sync. Don't touch the setImageData: and imageData methods - in fact,
you can even remove them from your custom subclass (you'll still be
able to get them using valueForKey: and setValue:forKey:).
Hope this helps.
Jeff
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden