Question

In a Cocoa App I would like to display a 2d array of floats in an NSImageView. To make the code as simple as possible, start off by converting the data from float to NSData:

// dataArray: an Nx by Ny array of floats
NSMutableData *nsdata = [NSMutableData dataWithCapacity:0];
long numPixels = Nx*Ny;
for (int i = 0; i < numPixels; i++) {
    [nsdata appendBytes:&dataArray[i] length:sizeof(float)];
}

and now try to display the data (the display is left blank):

[theNSImageView setImage:[[NSImage alloc] initWithData:nsdata]];

Is this the correct approach? Is a CGContext needed first? I was hoping to accomplish this with NSData.

I have noted the earlier Stack posts: 32 bit data, close but in reverse, almost worked but no NSData, color image data here, but not much luck getting variations on these working. Thanks for any suggestions.

Was it helpful?

Solution 2

Ok got it to work. I had tried the NSBitmapImageRep before (thanks Tim) but the part I was missing was in properly converting my floating point data to a byte array. NSData doesn't do that and returns nil. So the solution was not so much in needing to build up an NSImage float-by-float. In fact, one can similarly build up a bitmapContext (using CGBitmapContextCreate (mentioned by HotLicks above)) and that works too, once the floating point data has been represented properly.

OTHER TIPS

You can use an NSBitmapImageRep to build up an NSImage float-by-float.

Interestingly, one of its initialisers has the longest method name in all of Cocoa:

- (id)initWithBitmapDataPlanes:(unsigned char **)planes 
                    pixelsWide:(NSInteger)width 
                    pixelsHigh:(NSInteger)height 
                 bitsPerSample:(NSInteger)bps 
               samplesPerPixel:(NSInteger)spp 
                      hasAlpha:(BOOL)alpha 
                      isPlanar:(BOOL)isPlanar 
                colorSpaceName:(NSString *)colorSpaceName 
                  bitmapFormat:(NSBitmapFormat)bitmapFormat 
                   bytesPerRow:(NSInteger)rowBytes 
                  bitsPerPixel:(NSInteger)

It's well documented at least. Once you've built it up by supplying float arrays in planes you can then get the NSImage to put in your view:

NSImage *image = [[NSImage alloc] initWithCGImage:[bitmapImageRep CGImage] size:NSMakeSize(width,height)];

Or, slightly cleaner

NSImage *image = [[[NSImage alloc] init] autorelease];
[im addRepresentation:bitmapImageRep];

There is an initialiser which just uses an NSData container:

+ (id)imageRepWithData:(NSData *)bitmapData

although that depends on your bitmapData containing one of the correct bitmap formats.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top