Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get image data from QTKit without color or gamma correction in Snow Leopard?

Since Snow Leopard, QTKit is now returning color corrected image data from functions like QTMovies frameImageAtTime:withAttributes:error:. Given an uncompressed AVI file, the same image data is displayed with larger pixel values in Snow Leopard vs. Leopard.

Currently I'm using frameImageAtTime to get an NSImage, then ask for the tiffRepresentation of that image. After doing this, pixel values are slightly higher in Snow Leopard.

For example, a file with the following pixel value in Leopard:

[0 180 0]

Now has a pixel value like:

[0 192 0]

Is there any way to ask a QTMovie for video frames that are not color corrected? Should I be asking for a CGImageRef, CIImage, or CVPixelBufferRef instead? Is there a way to disable color correction altogether prior to reading in the video files?

I've attempted to work around this issue by drawing into a NSBitmapImageRep with the NSCalibratedColroSpace, but that only gets my part of the way there:

// Create a movie
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys :
                      nsFileName, QTMovieFileNameAttribute,
                      [NSNumber numberWithBool:NO], QTMovieOpenAsyncOKAttribute,
                      [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
                      [NSNumber numberWithBool:NO], QTMovieLoopsBackAndForthAttribute,
                      (id)nil];
_theMovie = [[QTMovie alloc] initWithAttributes:dict error:&error];


// ....    

NSMutableDictionary *imageAttributes = [NSMutableDictionary dictionary];
[imageAttributes setObject:QTMovieFrameImageTypeNSImage forKey:QTMovieFrameImageType];
[imageAttributes setObject:[NSArray arrayWithObject:@"NSBitmapImageRep"] forKey: QTMovieFrameImageRepresentationsType];
[imageAttributes setObject:[NSNumber numberWithBool:YES] forKey:QTMovieFrameImageHighQuality];

NSError* err = nil;
NSImage* image = (NSImage*)[_theMovie frameImageAtTime:frameTime withAttributes:imageAttributes error:&err];


// copy NSImage into an NSBitmapImageRep (Objective-C)
NSBitmapImageRep* bitmap = [[image representations] objectAtIndex:0]; 

// Draw into a colorspace we know about
NSBitmapImageRep *bitmapWhoseFormatIKnow = [[NSBitmapImageRep alloc] 
                                                initWithBitmapDataPlanes:NULL 
                                                pixelsWide:getWidth() 
                                                pixelsHigh:getHeight()
                                                bitsPerSample:8 
                                                samplesPerPixel:4 
                                                hasAlpha:YES 
                                                isPlanar:NO
                                                colorSpaceName:NSCalibratedRGBColorSpace 
                                                bitmapFormat:0
                                                bytesPerRow:(getWidth() * 4)
                                                bitsPerPixel:32];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmapWhoseFormatIKnow]];
[bitmap draw];
[NSGraphicsContext restoreGraphicsState];

This does convert back to a 'Non color corrected' colorspace, but the color values NOT are exactly the same as what is stored in the Uncompressed AVI files we are testing with. Also this is much less efficient because it is converting from RGB -> "Device RGB" -> RGB.

Also, I am working in a 64-bit application, so dropping down to the Quicktime-C API is not an option.

Thanks for your help.

like image 853
Nick Haddad Avatar asked Jan 12 '10 21:01

Nick Haddad


People also ask

What will the image be look like if we do not apply the gamma correction?

Gamma is an important but seldom understood characteristic of virtually all digital imaging systems. It defines the relationship between a pixel's numerical value and its actual luminance. Without gamma, shades captured by digital cameras wouldn't appear as they did to our eyes (on a standard monitor).

Why gamma correction is needed?

Gamma correction can be used to control the overall brightness of an image. It can be used with images that are found to be either bleached out or too dark [12]. Expansion and compression of pixel intensity values are desired for darker and faded images [51].

How does gamma affect image?

Your monitor's gamma tells you its pixels' luminance at every brightness level, from 0-100%. Lower gamma makes shadows looks brighter and can result in a flatter, washed out image, where it's harder to see brighter highlights. Higher gamma can make it harder to see details in shadows.

What does gamma correction do in Photoshop?

What Is Gamma Correction in Photoshop? Gamma correction enables you to adjust how an image is displayed on your monitor. The wrong gamma settings can make your image too dark or faded, for example. It's different from brightness settings because it adjusts both light and dark tones.


1 Answers

This is what you're running up against: http://support.apple.com/kb/ht3712 Also described here in reference to QT: http://developer.apple.com/library/mac/#technotes/tn2227/_index.html

There is supposed to be an opt-out flag for ColorSync (which is automatic and silent), but because ColorSync goes back to the "Carbon-iferous era" there's a lot of confusion about how to disable it from a 64-bit app. It may even exist, and just have no documentation. But even Adobe has not figured it out AFAIK (64 bit Photoshop for OS X???) [EDIT: Actually, maybe they did with CS5, or found a workaround... so if you have any friends who work there maybe they can be a resource ;) However, I think even their colors may come out different on 64 bit OS X vs Windows or 32 bit].

The first link tells how to force a gamma value of 1.8 system-wide and non-programmatically. Just pointing it out - it probably is only of limited use for your application, but good to know.

The usual way to disable colorsync is/was

GraphicsImportSetFlags( gi, kGraphicsImporterDontUseColorMatching ); 

But I don't know if that's going to work in a 64-bit application (pretty sure it does not). In fact, a lot of things related to ColorSync are more difficult, maybe not yet possible, in 64-bit. Just search "site:apple.com colorsync 64 bit".

If I find something better I'll edit my answer. Just thought this would help you know the enemy, so to speak.

Another edit: (Re)Tagging your videos might mitigate or eliminate this problem too, since ColorSync treats untagged videos a certain way (see links) and operates on them differently depending on the tags. What is the color profile of the videos? Try sRGB maybe?

like image 56
Rab Avatar answered Sep 23 '22 04:09

Rab