Creating a color image with NSBitmapImageRep and greyscale data
-
I need to create a color image from greyscale data. This is because I
would like to display the image in false color to aid in
visualization. I have tried using the CIColorMap core image filter on
a CIImage created from a 16 bit greyscale NSBitmapImageRep, but this
does not work (you just get a modified greyscale image, not color).
Unfortunately, there is nothing in the documentation for CIColorMap
that says you can only apply this filter to a color image, but I am
assuming that that is the case. So, I though I would transform the
greyscale image data into color RGB data and create a color
NSBitmapImageRep, but this is not working either. Here's what I have:
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:width
pixelsHigh:height
bitsPerSample:16
samplesPerPixel:3
hasAlpha:NO
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:0
bytesPerRow:3840
bitsPerPixel:48];
unsigned char *bitmapData = [bitmap bitmapData];
uint16_t RGBData[921600];
int pixel, color;
int numPixels = height*width;
for (pixel=0; pixel<numPixels; pixel++) {
for (color=0; color<3; color++) {
RGBData[pixel+color] = pixels[pixel];
}
}
memcpy(bitmapData, RGBData, [bitmap bytesPerRow] * [bitmap
pixelsHigh]);
'pixels' is an array of 16 bit integers that contain the data for the
16 bit greyscale image that is 640 x 480. This code actually produces
a three mini-greyscale images inside the main image.
Does anyone know hat I'm doing wrong? Any suggestions for creating a
color image from greyscale data?
Thanks! -
David Spooner Re: Creating a color image with NSBitmapImageRep and greyscale data Nov 28 2007, 04:34On 27-Nov-07, at 5:38 PM, Jason Horn wrote:
> I need to create a color image from greyscale data. This is because
> I would like to display the image in false color to aid in
> visualization. I have tried using the CIColorMap core image filter
> on a CIImage created from a 16 bit greyscale NSBitmapImageRep, but
> this does not work (you just get a modified greyscale image, not
> color). Unfortunately, there is nothing in the documentation for
> CIColorMap that says you can only apply this filter to a color
> image, but I am assuming that that is the case. So, I though I
> would transform the greyscale image data into color RGB data and
> create a color NSBitmapImageRep, but this is not working either.
> Here's what I have:
>
> NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
> initWithBitmapDataPlanes:NULL
> pixelsWide:width
> pixelsHigh:height
> bitsPerSample:16
> samplesPerPixel:3
> hasAlpha:NO
> isPlanar:NO
> colorSpaceName:NSCalibratedRGBColorSpace
> bitmapFormat:0
> bytesPerRow:3840
> bitsPerPixel:48];
> unsigned char *bitmapData = [bitmap bitmapData];
> uint16_t RGBData[921600];
> int pixel, color;
> int numPixels = height*width;
> for (pixel=0; pixel<numPixels; pixel++) {
> for (color=0; color<3; color++) {
> RGBData[pixel+color] = pixels[pixel];
The preceding line sets the r, g and b components uniformly for each
output pixel, so you'll always get grey. You might try distributing
each input pixel p across r, g and b along the lines of...
int bpr = [bitmap bytesPerRow];
for (int i = 0; i < height; ++i) {
char *row = bitmapData + i * bpr;
for (int j = 0; j < width; ++j) {
uint16_t p = pixels[i * width + j];
unsigned char *rgb = row + j * 3;
rgb[0] = p & 0x3f;
rgb[1] = (p >> 6) & 0x3f;
rgb[2] = (p >> 12);
}
}
> }
> }
> memcpy(bitmapData, RGBData, [bitmap bytesPerRow] * [bitmap
> pixelsHigh]);
> 'pixels' is an array of 16 bit integers that contain the data for
> the 16 bit greyscale image that is 640 x 480. This code actually
> produces a three mini-greyscale images inside the main image.
>
> Does anyone know hat I'm doing wrong? Any suggestions for creating
> a color image from greyscale data?
>
> Thanks!_______________________________________________
Cheers,
dave -
David Spooner Re: Creating a color image with NSBitmapImageRep and greyscale data Nov 28 2007, 04:55Sorry, I meant to also say that an alternative to this quick and
dirty approach is to consider the input greyscale value as the hue
component of an HSB (or related) colorspace and perform a standard
conversion from HSB to RGB (using a fixed saturation and brightness).
dave
On 27-Nov-07, at 8:34 PM, David Spooner wrote:
> The preceding line sets the r, g and b components uniformly for each
> output pixel, so you'll always get grey. You might try distributing
> each input pixel p across r, g and b along the lines of...
>
> int bpr = [bitmap bytesPerRow];
>
> for (int i = 0; i < height; ++i) {
> char *row = bitmapData + i * bpr;
> for (int j = 0; j < width; ++j) {
> uint16_t p = pixels[i * width + j];
> unsigned char *rgb = row + j * 3;
> rgb[0] = p & 0x3f;
> rgb[1] = (p >> 6) & 0x3f;
> rgb[2] = (p >> 12);
> }
> }
-
Thanks Dave,
I was aware that the code I gave will still give a grey image. The
problem is that the image is also munged somehow. the resulting image
was actually a mosaic of three separate grey images within the borders
of the main image,with the rest of the space being black. Also, the
reason that I was attempting this was in hopes that, even though
technically still grey, CIColorMap would treat the image differently,
and yield a color image.
On Nov 27, 2007, at 10:55 PM, David Spooner wrote:
>
> Sorry, I meant to also say that an alternative to this quick and
> dirty approach is to consider the input greyscale value as the hue
> component of an HSB (or related) colorspace and perform a standard
> conversion from HSB to RGB (using a fixed saturation and brightness).
>
> dave
>
> On 27-Nov-07, at 8:34 PM, David Spooner wrote:
>
>> The preceding line sets the r, g and b components uniformly for
>> each output pixel, so you'll always get grey. You might try
>> distributing each input pixel p across r, g and b along the lines
>> of...
>>
>> int bpr = [bitmap bytesPerRow];
>>
>> for (int i = 0; i < height; ++i) {
>> char *row = bitmapData + i * bpr;
>> for (int j = 0; j < width; ++j) {
>> uint16_t p = pixels[i * width + j];
>> unsigned char *rgb = row + j * 3;
>> rgb[0] = p & 0x3f;
>> rgb[1] = (p >> 6) & 0x3f;
>> rgb[2] = (p >> 12);
>> }
>> }
-
Dave,
Actually, there was a bug in my code. That loop should have been:
for (pixel=0; pixel<numPixels; pixel++) {
RGBData[RGBpixel] = pixels[pixel];
RGBData[RGBpixel+1] = pixels[pixel];
RGBData[RGBpixel+2] = pixels[pixel];
RGBpixel += 3;
}
So, now I have a color image (that is grey), but CIColorMap still does
not produce a color image. Perhaps I don't understand how CIColorMap
works.
On Nov 27, 2007, at 10:55 PM, David Spooner wrote:
>
> Sorry, I meant to also say that an alternative to this quick and
> dirty approach is to consider the input greyscale value as the hue
> component of an HSB (or related) colorspace and perform a standard
> conversion from HSB to RGB (using a fixed saturation and brightness).
>
> dave
>
> On 27-Nov-07, at 8:34 PM, David Spooner wrote:
>
>> The preceding line sets the r, g and b components uniformly for
>> each output pixel, so you'll always get grey. You might try
>> distributing each input pixel p across r, g and b along the lines
>> of...
>>
>> int bpr = [bitmap bytesPerRow];
>>
>> for (int i = 0; i < height; ++i) {
>> char *row = bitmapData + i * bpr;
>> for (int j = 0; j < width; ++j) {
>> uint16_t p = pixels[i * width + j];
>> unsigned char *rgb = row + j * 3;
>> rgb[0] = p & 0x3f;
>> rgb[1] = (p >> 6) & 0x3f;
>> rgb[2] = (p >> 12);
>> }
>> }
-
David Spooner Re: Creating a color image with NSBitmapImageRep and greyscale data Nov 28 2007, 05:53Yes, the documentation for the CIColorMap filter is somewhat vague.
There is a posting on the quartz-dev list which points to an example
usage in the Core Imager Fun House application and states that the
gradient image (2nd argument) is a 1xN lookup table mapping greyscale
values (appropriately scaled?) to rgb values...
dave
On 27-Nov-07, at 9:37 PM, Jason Horn wrote:
> Dave,
>
> Actually, there was a bug in my code. That loop should have been:
>
> for (pixel=0; pixel<numPixels; pixel++) {
> RGBData[RGBpixel] = pixels[pixel];
> RGBData[RGBpixel+1] = pixels[pixel];
> RGBData[RGBpixel+2] = pixels[pixel];
> RGBpixel += 3;
> }
>
> So, now I have a color image (that is grey), but CIColorMap still
> does not produce a color image. Perhaps I don't understand how
> CIColorMap works.
>


