I have a structure which includes a pointer to a data set, which in this case is a 16-bit grayscale image. I want to convert this data to an NSImage so that I can display it, and then save it as a .TIF file. The route from the manuals appears to be something like:
(Create *myNSImData from frame->image, which is a pointer)
NSImage *TestImage = [[NSImage alloc] initWithData : myNSImData];
(display TestImage, save it, whatever else)
[TestImage release];
I am lost as to how to create the NSData object and assure it contains the array of 16-bit data. Attempts to recast the pointer give warnings and no data. I could simply increment the pointers, transferring one byte at a time from frame->image to the data object, but I don't understand how to communicate the array structure to the data object. Any ideas? Thanks
MORE ATTEMPTS USING YOUR SUGGESTION I can convert this data to a .TIF file in the following manner:
for (uint32 row = 0 ; row < MaxHeight ; row++)
{
for (uint32 column = 0;column< MaxWidth;column++)
{
tempData = (uint8_t)*frame->image; //first byte
*frame->image++;
buf[2 * column + 1] = (unsigned char) tempData;
tempData = (uint8_t)*frame->image; //second byte
*frame->image++;
buf[2 * column] = (unsigned char) tempData;
}
TIFFWriteScanline(tiffile,buf,row,0);
}
With the .TIF file thus generated, I can create an NSImage and display it:
NSImage *TestImage = [[[NSImage alloc] initWithContentsOfFile:inFilePath] autorelease];
[viewWindow setImage: TestImage];
My question now becomes - can I create an NSData object that I can display in the same way? I have tried the following (product is the height*width of the image):
NSData *ReadImage = [[[NSData alloc] initWithBytes: frame->image length:2*product] autorelease] ;
NSImage *NewImage = [[[NSImage alloc] initWithData:ReadImage] autorelease];
NSSize newSize;
newSize.height = MaxHeight; //height of the image
newSize.width = MaxWidth; //width of the image
[NewImage setSize:newSize];
[viewWindow setImage: NewImage];
When I try this, nothing displays. I have also tried creating an array of uint16_t which has the data, and serving up the pointer to that - again, nothing displays. Any ideas? E.g. do I have to tell the NSData that I am using 2 bytes per pixel, or something like that? Thanks Monty Wood
To create an NSData
object containing a block to which you have a pointer, you should use one of the three methods that start with initWithBytes:
, or, to create an autoreleased NSData
object, use one of the class methods that start with dataWithBytes:
UPDATE: I think that if you want to create an NSImage
directly from an NSData
, the data needs to include the appropriate headers/magic numbers so that NSImage
can figure out what the representation is. You should look at NSBitmapImageRep
and the Images chapter of the Cocoa Drawing Guide for raw image data.