• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Saving NSImage with compression
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Prev by Date: Re: Sublclassing NSThread
  • Next by Date: Re: Sublclassing NSThread
  • Previous by thread: Re: CALayer shadow and animation
  • Next by thread: getObjects:andKeys
  • Index(es):
    • Date
    • Thread