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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to