By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,659 Members | 1,945 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,659 IT Pros & Developers. It's quick & easy.

How to extract RGB as unsigned char * from unsigned char * of 24 bit BMP Color images

P: 30
Dear All,


Now, I am stuck above question so long and I would like to get Red, Green and Blue as unsigned char * each from unsigned char * of 24 bit BMP Color images.

e.g
unsigned char * image = new unsigned char [ width * height];
unsigned char * red = new unsigned char [ width * height];
unsigned char * blue= new unsigned char [ width * height];
unsigned char * green = new unsigned char [ width * height];

the coding are as follows

bool MainDlg::Test()
{

char *colorFileLocation = "C\\Images\\white.bmp";
colorSize = Load_Colorfile_to_memory(colorFileLocation, &cColorContent);

FILE *colorF;
colorF = fopen(colorFileLocation, "rb");

BITMAPFILEHEADER colorBmfh;
fread(&colorBmfh,sizeof(BITMAPFILEHEADER),1,colorF );

BITMAPINFOHEADER colorBmih;
fread(&colorBmih,sizeof(BITMAPINFOHEADER),1,colorF );

int colorBmWidth = colorBmih.biWidth;
int colorBmHeight = colorBmih.biHeight;
int colorPitch = colorBmWidth;

unsigned char *colorImage = new unsigned char[colorBmWidth * colorBmHeight * 3];
colorImage = cColorContent;
unsigned char *Red = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *Green = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *Blue = new unsigned char[colorBmWidth * colorBmHeight ];


/*for (int k =0;k<colorBmHeight;k++)
{
for (int i =0;i<colorBmWidth;i++)
{
Red[k*colorBmHeight + i] = colorImage[k*colorBmHeight+ i*3];
Green[k*colorBmHeight + i] = colorImage[k*colorBmHeight+ i*3+1];
Blue[k*colorBmHeight + i] = colorImage[k*colorBmHeight+ i*3+2];
}
}*/


unsigned char *cImage = GetColorImages(colorBmWidth, colorBmHeight, Red, colorPitch);

Please advise me and looking forward to hearing from you soon.

Thanks in advance
Feb 24 '10 #1
Share this Question
Share on Google+
8 Replies


jkmyoung
Expert 100+
P: 2,057
Either:
1. You need to set colorImage to bytes instead of char

or

1. You need to convert into 24 bit sequences. Each row in a bmp is a multiple of (4 bytes).
2. You need to offset correctly.

The total width of each row in bytes will be (colorBmWidth / 4 * 3 + (colorBmWidth % 4))*4;

http://en.wikipedia.org/wiki/BMP_fil...at#Bitmap_data
Feb 24 '10 #2

P: 30
Hi,


Thanks for your prompt reply. As for me, I would like to extract out red, green, blue, unused as each unsigned char * since my dll based on native C or C++ only. As well, the other SDK only accept as I mentioned R,G,B differently then combine as one color byte. Please advise me and looking forward to hearing from you soon.



Best regards
Feb 25 '10 #3

jkmyoung
Expert 100+
P: 2,057
Are you planning on running this on any system but your own?

Find out the sizeof(char) on your system. If it works out to be 1 then you don't have to do anything extra.

To clarify the last point, the pixel's data has 000's at the end of a row. Eg a 2X2 row data would look something like (in hex)

pixel (0,0):
FF 11 11
pixel (0,1):
22 FF 22
end of row: (6 bytes used. fill to 8)
00 00

pixel (1,0):
33 33 FF
pixel (1,1):
44 44 44
end of row: (6 bytes used. fill to 8)
00 00

So the pixel data looks something like:
FF 11 11 22 FF 22 00 00
33 33 FF 44 44 44 00 00

You just need to add the extra bits per row.
you have:
[k*colorBmHeight+ i*3]
(height? should be width logically)

Calculate the number of bytes in a row. Something like:
((colorBmWidth * 3 / 4) + colorBmWidth % 4) * 4
Feb 25 '10 #4

P: 30
Hi,


Thank you your prompt reply and

I am planning on running in native C++ using VS 2008 and integrate with

The sizeof(char) on your system is 1 byte and I couldn't well where I put these lines in my coding.

[k*colorBmHeight+ i*3]
The image size is let say 1976 x 1472

Calculate the number of bytes in a row. Something like:
((colorBmWidth * 3 / 4) + colorBmWidth % 4) * 4

I am looking forward to hearing from you.


Best regards
Feb 26 '10 #5

jkmyoung
Expert 100+
P: 2,057
What you have now is:
[k*colorBmHeight+ i*3];

colorBmHeight should instead be the byte size of a row.

int sizeOfRow = ((colorBmWidth * 3 / 4) + colorBmWidth % 4) * 4 ;

So it becomes:
[k*sizeOfRow+ i*3];
Feb 26 '10 #6

P: 30
Hi,


Now access violation writing location in after k = 491
// For Color Images
unsigned char *colorImage = new unsigned char[colorBmWidth * colorBmHeight * 3];
colorImage = cColorContent;
unsigned char *red = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *green = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *blue = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *unused = new unsigned char[colorBmWidth * colorBmHeight ];

// Convert from unsigned char * to unsigned long *
int sizeOfRow = ((colorBmWidth * 3 / 4) + colorBmWidth % 4) * 4 ;

for (int k =0;k<colorBmHeight;k++)
{
for (int i =0;i<colorBmWidth;i++)
{
//red[(k*colorBmWidth) + i] = colorImage[(k*colorBmWidth) + (i*3)];
red[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)];
green[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)+ 1];
blue[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)+ 2];
unused[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3) + 3];
//unused[(k*sizeOfRow) + i] = 0;
}
}
Mar 1 '10 #7

P: 30
Hi,


Now error came out after red buffer used sizeOfRow instead of colorBmWidth.

// For Color Images
unsigned char *colorImage = new unsigned char[colorBmWidth * colorBmHeight * 3];
colorImage = cColorContent;
unsigned char *red = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *green = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *blue = new unsigned char[colorBmWidth * colorBmHeight ];
unsigned char *unused = new unsigned char[colorBmWidth * colorBmHeight ];

// Convert from unsigned char * to unsigned long *
int sizeOfRow = ((colorBmWidth * 3 / 4) + colorBmWidth % 4) * 4 ;

for (int k =0;k<colorBmHeight;k++)
{
for (int i =0;i<colorBmWidth;i++)
{
//red[(k*colorBmWidth) + i] = colorImage[(k*colorBmWidth) + (i*3)];
red[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)]; // access violation
writing location in after k = 491

green[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)+ 1];
blue[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3)+ 2];
unused[(k*sizeOfRow) + i] = colorImage[(k*sizeOfRow) + (i*3) + 3];
//unused[(k*sizeOfRow) + i] = 0;
}
}

could it be possible to resue the 24 bits color images into R, G and B of 8 bits then again as 8 bits of R, G and B into 24 bits of color images for verification test before putting into third party SDKs.


Thanks and best regards
Mar 1 '10 #8

jkmyoung
Expert 100+
P: 2,057
Sorry, formula was wrong:

int sizeOfRow = colorBmWidth * 3 + colorBmWidth % 4;

overcomplicated it.
Mar 1 '10 #9

Post your reply

Sign in to post your reply or Sign up for a free account.