Black and White graphics context - c++

I'm working in Quartz/Core-graphics. I'm trying to create a black and white, 1b per pixel graphics context.
I currently have a CGImageRef with a grayscale image (which is really black and white). I want to draw it into a black and white BitmapContext so I can get the bitmap out and compress it with CCITT-group 4. (For some reason Quartz won't let you save in any TIFF format other than LZW).
So, I need the 1bit per pixel data. I figure that drawing into a 1bpp context would do that. However, it won't let me create the context with:
context = CGBitmapContextCreate (data,
pixelsWide,
pixelsHigh,
1,
pixelsWide/8,
CGColorSpaceCreateDeviceGray(),
kCGImageAlphaNone
);
Is there a colorspace smaller than gray?

Even if 1-bit bitmaps were supported, if pixelsWide is not a multiple of 8, then the number of bytes per row is not an integer: for example, if your image is 12 pixels wide, then the number of bytes per row is one and a half. Your division expression will truncate this to one byte per row, which is wrong.
But that's if 1-bit bitmaps were supported, which they aren't.

Related

RGB color in 24 bitmap image and 16 bitmap image

1)
I want to know the value of red color in 24 bitmap image.
pixel is represented by 24bits, where there are 8 bits for each of the red, green, and blue (RGB) values
Suppose I open the 24 bitmap image, and save the data in unsigned char Array A.
i,e) ( A[0],A[1],A[2] ) is the first pixel value of the 24 bitmap image.
Then what is the value of Red color?
I think 24 bitmap image color order(?) is 'RGB', So A[0] is the red color value. Am I right?
2)
In 16 bitmap image, pixel is represented by 16 bits, where there are 5 bits for each of the red, green, and blue (RGB) values .
Suppose I open the 16 bitmap image, and save the data in unsigned short Array B.
i,e) B[0] is the first pixel value of the 16 bitmap image.
In this situation, I want to know the value of red color.
I think the last 5 bit, i,e) 'A[0] & 31' is the value of blue color since the color order(?) of 16 bitmap image is 'RGB'
Am I right?
Bitmaps can be tough to work with in source code to retrieve its data. You first have to parse the file for its header and from its header you have to parse it and its data to know what type of bitmap image you are working with. Bitmaps have a lot of information stored. Logically speaking if the bitmap image is 24bits without transparency values for specifically a RGB type you then need to know if the image is compressed and by what compression method as well as other properties of a the file such as palette information, icon information, etc. so you know where to find the actual pixel data within that specific file. After you extract the raw data you then need to know how the information is stored. Here is were it can get tricky: it might be a RGB image but the data could be stored in the file in a direct RGB order or it could be reversed BGR. After that then it is a matter of knowing which orientation the image data is stored and if you need to flip it vertically, horizontally or both. Other than that if the color data is in the correct order and the image is in the proper orientation without compression then it should be without a doubt structured as this for unsigned char values:
Bitmap 24bits - 24/3 for RGB gives 8bits per channel or 1byte per channel.
Since an unsigned char is 1 byte in memory width, then each byte in the
appropriate order would represent each color channel. Consider the following:
// Considering data is in RGB order:
unsigned char colorData[3]; // Integer Base Range
colorData[0] = red byte [0, 255]
colorData[1] = green byte [0, 255]
colorData[2] = blue byte [0, 255]
As for the bitmap internal file structure(s) here is a good source for parsing its data: bmp

How to get grayscale value of pixels from grayscale image in xCode

I was wondering how to determine the equivalent of RGB values for a grayscale image. The original image is grayscale and everything I have found online is converting an RGB image pixel values to the grayscale pixel values. I already can read in the image. Ideally, this would be for xCode.
I was wondering if there was a class which would do this for me. If so, and you could point me to it, that would be great. I will read on it.
Any help is greatly appreciated.
NOTE: I am a beginner in C++ and do not have time to learn everything formally; I have to learn all of my programming on the fly.
You need more information to transform from a simple Greyscale to RGB, when you do reverse operation, the color information is "lost", as the three channels are set to same value(depending on the algorithm each channel will have a different/same weight in the final color computation).
Digital cameras, usually store more information per pixel, 12 bits per channel in 35mm and 14 bits per channel in medium format (those bits number are the average, some products offer less or even more quality).
Thanks to those additional bits per channel, the camera can compute the "real" color, or what it thinks is the real color based on some parameters.
TL;DR: You can't without more data from your source, in this case the image.
You can convert a gray value to RGB by setting each component of the RGB value to the gray value:
ColorRGB myColorRGB = ColorRGBMake(myGrayValue, myGrayValue, myGrayValue);

How to transform rgb (three bytes) to one byte for bitmap format?

I have data for every pixel red one byte, green one byte, blue one byte. I need to pack this to 8 bits bitmap, so I have only one byte for pixel. How to transform rgb (three bytes) to one byte for bitmap format ?
( I am using C++ and cannot use any external libraries)
I think you misunderstood how to form a bitmap structure. You do not need to pack (somehow) 3 bytes into one. That is not possible after all, unless you throw away information (like using special image formats GL_R3_G3_B2).
The BMP file format wiki page shows detailed BMP format : it is a header, followed by data. Now depending on what you set in your header, it is possible to form a BMP image containing RBG data component, where each component is one byte.
First you need to decide how many bits you want to allocate for each color.
3bit per color will overflow a byte (9bits)
2bits per color will underflow;
In three byte RGB bitmap you have one byte to represent each color's intensity. Where 0 is minimum and 255 is max intensity. When you convert it to 1 byte bitmap (assuming you will choose 2bits per color ) transform should be:
1-byte red color/64
i.e you will get only 4 shades out of a spectrum of 265 shades per color.
First you have to produce 256 colors palette that best fits your source image.
Then you need to dither the image using the palette you've generated.
Both problems have many well-known solutions. However, it's impossible to produce high-quality result completely automatic: for different source images, different approaches work best. For example, here's the Photoshop UI that tunes the parameters of the process:

how go get RGB values of ROI selected in depth stream

I wrote an simple kinect application where I'm accessing the depth values to detect some objects. I use the following code to get the depth value
depth = NuiDepthPixelToDepth(pBufferRun);
this will give me the depth value for each pixel. Now I want to subselect a region of the image, and get the RGB camera values of this corresponding region.
What I'm not sure about:
do I need to open a color image stream?
or is it enough to just convert the depth into color?
how do I use NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution?
I'm fine with the simplest solution where I have a depth frame and a color frame, so that I can select a ROI with opencv and then crop the color frame accordingly.
do I need to open a color image stream?
Yes. You can get the coordinates in the colour frame without opening the stream, but you won't be able to do anything useful with them because you'll have no colour data to index into!
or is it enough to just convert the depth into color?
There's no meaningful conversion of distance into colour. You need two image streams, and a co-ordinate conversion function.
how do I use NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution?
That's a terribly documented function. Go take a look at NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution instead, because the function arguments and documentation actually make sense! Depth value and depth (x,y) coordinate in, RGB (x,y) coordinate out. Simple.
To get the RGB data at some given coordinates, you must first grab an RGB frame using NuiImageStreamGetNextFrame to get an INuiFrameTexture instance. Call LockRect on this to get a NUI_LOCKED_RECT. The pBits property of this object is a pointer to the first pixel of the raw XRGB image. This image is stored row wise, in top-to-bottom left-to-right order, with each pixel being represented by 4 sequential bytes representing a padding byte then R, G and B follwing it.
The pixel at position (100, 200) is therefore at
lockedRect->pBits[ ((200 * width * 4) + (100 * 4) ];
and the byte representing the red channel should be at
lockedRect->pBits[ ((200 * width * 4) + (100 * 4) + 1 ];
This is a standard 32bit RGB image format, and the buffer can be freely passed to your image manipulation library of choice... GDI, WIC, OpenCV, IPL, whatever.
(caveat... I'm not totally certain I have the pixel byte ordering correct. I think it is XRGB, but it could be XBGR or BGRX, for example. Testing for which one is actually being returned should be trivial)

1bpp Monochromatic BMP

I ran a demo bmp file format helper program "DDDemo.exe" to help me visualize the format of a 32x1 pixel bmp file (monochromatic). I'm okay with the the two header sections but dont seem to understand the color table and pixel bits portions. I made two 32x1 pixel bmp files to help me compare (please see attached).
Can someone assit me understand how the "pixel bits" relates to the color map?
UPDATE: After some trial and error I finally was able to write a 32x1 pixel monochromatic BMP. Although it has different pixel bits as the attached images, this tool helped with the header and color mapping concept. Thank you for everyones input.
An unset bit in the PIXEL BITS refers to the first color table entry (0,0,0), black, and a set bit refers to the second color table entry (ff,ff,ff), white.
"The 1-bit per pixel (1bpp) format supports 2 distinct colors, (for example: black and white, or yellow and pink). The pixel values are stored in each bit, with the first (left-most) pixel in the most-significant bit of the first byte. Each bit is an index into a table of 2 colors. This Color Table is in 32bpp 8.8.8.0.8 RGBAX format. An unset bit will refer to the first color table entry, and a set bit will refer to the last (second) color table entry." - BMP file format
The color table for these images is simply indicating that there are two colors in the image:
Color 0 is (00, 00, 00) -- pure black
Color 1 is (FF, FF, FF) -- pure white
The image compression method shown (BI_RGB -- uncompressed) doesn't make sense with the given pixel data and images, though.