Saving NSImage with compression
Saving NSImage with compression
- Subject: Saving NSImage with compression
- From: Antonio Nunes <email@hidden>
- Date: Wed, 17 Dec 2008 09:32:21 +0000
Hi,
I create NSImages by loading graphics from disk. I then want to write
those images back out to disk, but that can result in ballooning file
sizes. For instance, I may load a JPG image that is less than 800K on
disk. When I write the image back out though (with the likes of [coder
encodeObject:image forKey:@"someKey"]) it may result in a file of over
9MB on disk. I haven't found a way to specify saving using the
original compression (and, from some recent posts in the archives, I
gather there is none).
So I wrote some code to try and force a user chosen compression when
saving a bitmap based image object:
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
NSData *data = nil;
NSUInteger count = 0;
ANDocumentImageCompression compressionType = [[[NSUserDefaults
standardUserDefaults] objectForKey:ANDefaultImageCompressionTypeKey]
integerValue];
for (NSImageRep *rep in [image representations]) {
if ([[rep class] isEqual:[NSEPSImageRep class]]) {
data = [(NSEPSImageRep *)rep EPSRepresentation];
} else if ([[rep class] isEqual:[NSPDFImageRep class]]) {
data = [(NSPDFImageRep *)rep PDFRepresentation];
} else if ([[rep class] isEqual:[NSPICTImageRep class]]) {
data = [(NSPICTImageRep *)rep PICTRepresentation];
} else if ([[rep class] isEqual:[NSBitmapImageRep class]]) {
switch (compressionType) {
case NSTIFFFileType:
data = [(NSBitmapImageRep *)rep
representationUsingType:NSTIFFFileType properties:[NSDictionary
dictionaryWithObject:[NSNumber numberWithInteger:NSTIFFCompressionLZW]
forKey:NSImageCompressionMethod]];
break;
case NSJPEGFileType:
data = [(NSBitmapImageRep *)rep
representationUsingType:NSJPEGFileType properties:[NSDictionary
dictionaryWithObject:[NSNumber numberWithInteger:0.8]
forKey:NSImageCompressionFactor]];
break;
case NSPNGFileType:
data = [(NSBitmapImageRep *)rep
representationUsingType:NSPNGFileType properties:nil];
break;
default:
data = [(NSBitmapImageRep *)rep TIFFRepresentation];
break;
}
}
if (data) {
[coder encodeObject:data forKey:[IMAGE_DATA_KEY
stringByAppendingFormat:@"%i", count++]];
}
}
[coder encodeObject:[NSNumber numberWithInteger:count]
forKey:IMAGE_DATA_COUNT_KEY];
[coder encodeObject:NSStringFromSize(image.size)
forKey:IMAGE_SIZE_KEY];
}
This doesn't appear to work very well however: The JPG compression
option usually results in greatly reduced file sizes, but the PNG and
LZW compression options can result in file sizes many times greater
than the uncompressed option. Am I going about this the wrong way? Did
I overlook a there a better, higher level, way of writing out an
NSImage object, using compression? If the code itself is all-right,
why can the LZW and PNG compression increase the file size, rather
than reduce it? And lastly: are there any other gotchas I need to be
aware of, by not saving out the NSImage object as a whole?
António
P.S.
For completeness, here follows the code that reads the data back in:
- (id)initWithCoder:(NSCoder *)coder
{
[super initWithCoder:coder];
if ([coder containsValueForKey:IMAGE_DATA_COUNT_KEY]) {
NSUInteger i, count = [[coder
decodeObjectForKey:IMAGE_DATA_COUNT_KEY] integerValue];
image = [[NSImage alloc] initWithData:[coder decodeObjectForKey:
[IMAGE_DATA_KEY stringByAppendingFormat:@"%i", 0]]];
for (i = 1; i < count; i++) {
NSData *data = [coder decodeObjectForKey:[IMAGE_DATA_KEY
stringByAppendingFormat:@"%i", i]];
[image addRepresentation:[[[NSImageRep imageRepClassForData:data]
alloc] initWithData:data]];
}
}
[image setScalesWhenResized:YES];
[image setDataRetained:YES];
[image setSize:NSSizeFromString([coder
decodeObjectForKey:IMAGE_SIZE_KEY])];
return self;
}
-----------------------------------------------------------
And could you keep your heart in wonder
at the daily miracles of your life,
your pain would not seem less wondrous
than your joy.
--Kahlil Gibran
-----------------------------------------------------------
-----------------------------------------------
Touch is a language without words
-----------------------------------------------
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden