Due to the way that cacheing works on NSImage
, I've often found it more effective to actually grab the NSImageRep
if I know what the type is.
In our code, we found that the most reliable way to save off images is in their original format, but that requires either saving off the data in its original format somewhere else, or requesting the data from the NSImageRep
. Unfortunately, there's not a generic -(NSData*)data
method of NSImageRep
, so we ended up specifically checking for various types of NSImageRep
and saving them off depending on what we knew them to be.
Fortunately, loading is simple, as NSImage::initWithData:
will figure out the type based on the data.
Here's our long-standing code for doing this. Basically, it prefers PDF then EPS then it makes a TIFF of anything it doesn't understand.
+ (NSData*) dataWithImage:(NSImage*)image kindString:( NSString**)kindStringPtr
{
if (!image)
return nil;
NSData *pdfData=nil, *newData=nil, *epsData=nil, *imageData=nil;;
NSString *kindString=nil;
NSArray *reps = [image representations];
for (NSImageRep *rep in reps) {
if ([rep isKindOfClass: [NSPDFImageRep class]]) {
// we have a PDF, so save that
pdfData = [(NSPDFImageRep*)rep PDFRepresentation];
PDFDocument *doc = [[PDFDocument alloc] initWithData:pdfData];
newData = [doc dataRepresentation];
if (newData && ([newData length]<[pdfData length])) {
pdfData = newData;
}
break;
}
if ([rep isKindOfClass: [NSEPSImageRep class]]) {
epsData = [(NSEPSImageRep*)rep EPSRepresentation];
break;
}
}
if (pdfData) {
imageData=pdfData;
kindString= @"pdfImage";
} else if (epsData) {
imageData=epsData;
kindString=@"epsImage";
} else {
// make a big copy
NSBitmapImageRep *rep0 = [reps objectAtIndex:0];
if ([rep0 isKindOfClass: [NSBitmapImageRep class]]) {
[image setSize: NSMakeSize( [rep0 pixelsWide], [rep0 pixelsHigh])];
}
imageData = [image TIFFRepresentation];
kindString=@"tiffImage";
}
if (kindStringPtr)
*kindStringPtr=kindString;
return imageData;
}
Once we have the NSData*
, it can be saved in a keyed archive, written to disk or whatever.
On the way back in, load in the NSData*
and then
NSImage *image = [[NSImage alloc] initWithData: savedData];
and you should be all set.