|
Use this project[^] to inject code into the remote process.
The code you inject should create the new button.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hi everyone,
I am novelty to Image Processing. Currently, I want to read the data of a monochrome BMP file into an 2D array using VC++ 2005. I read quite a number of articles about BMP file, but there's still a vague explanation concerning the monochrome one.
I know and understand on how to read its header and header information. However, when I read the data of it, the output is 205 for BLACK pixel which makes me very confusing. It should be 0 for Black pixel, right? In short, the followings are my questions:
1. How is data in monochrome BMP file stored?
2. Do I have to read it in RGB order or just one byte a time?
3. Do I have to manage the junk (useless) byte?
Thanks in advance.
Ing LengIeng
Software Developer
|
|
|
|
|
I think a monochomre bitmap is stored as 1 bits per pixel, so 1 byte contains 8 pixels, where every 0 is BLACK and every 1 is WHITE (or whatever you schoose to be foreground and background colors). So if you read 205 -> 11001101 -> WHITE PIXEL, BLACK PIXEL, WHITE, WHITE, BLACK, BLACK, WHITE, WHITE. (don't forget, the leftmost bit is the most significant)
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Thank you very much!
Ing LengIeng
Software Developer
|
|
|
|
|
You can use bitmasks to gain the pixels out of the bytes, so something like (just to explain and give you a starting point):
SetPixel(x , y, (bmp_byte & 1)?foreColor:backColor);
SetPixel(x + 1, y, (bmp_byte & 2)?foreColor:backColor);
SetPixel(x + 2, y, (bmp_byte & 4)?foreColor:backColor);
SetPixel(x + 3, y, (bmp_byte & 8)?foreColor:backColor);
SetPixel(x + 4, y, (bmp_byte & 16)?foreColor:backColor);
SetPixel(x + 5, y, (bmp_byte & 32)?foreColor:backColor);
SetPixel(x + 6, y, (bmp_byte & 64)?foreColor:backColor);
SetPixel(x + 7, y, (bmp_byte & 128)?foreColor:backColor);
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> Life: great graphics, but the gameplay sux. <
|
|
|
|
|
Thanks very much. I gain much understanding now.
Ing LengIeng
Software Developer
|
|
|
|
|
From BITMAPINFOHEADER documentation [^], about biBitCount member equal to 1:
The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if the bit is set, the pixel has the color of the second entry in the table.
Thus one byte of the bitmap array having value 205 represents eight adjacent pixels colors: 11001101 (1-second color of the color table, for instance black, 0-first entry of the color table, for instance white).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Oh! I see. Thank all of you very much for your useful reply.
One more thing! This might be a stupid question, but how can I convert from a Byte into those 8 bits?
Ing LengIeng
Software Developer
|
|
|
|
|
Member 2116736 wrote: but how can I convert from a Byte into those 8 bits?
A byte is already that set of bits.
If you need to extract single bit info you may:
- use the
shift and AND operators:
unsigned int getbit(BYTE byte, int bit){ return ( (byte >> bit) & 0x01; ) }
It may be used as follows:
void main()
BYTE byte = 205;
cout << (int) mb.byte << " decimal is ";
int i=8;
while (i--)
{
cout << getbit(byte, i);
}
cout << " binary " << endl;
} - use the 'union trick', i.e.
struct BitField
{
unsigned int bit0 : 1;
unsigned int bit1 : 1;
unsigned int bit2 : 1;
unsigned int bit3 : 1;
unsigned int bit4 : 1;
unsigned int bit5 : 1;
unsigned int bit6 : 1;
unsigned int bit7 : 1;
};
union MyByte
{
BYTE byte;
BitField bf;
};
That you may use this way:
bool main()
{
MyByte mb;
mb.byte = 205;
cout << (int) mb.byte << " decimal is ";
cout << mb.bf.bit7 << mb.bf.bit6 << mb.bf.bit5 << mb.bf.bit4 << mb.bf.bit3 << mb.bf.bit2 << mb.bf.bit1 << mb.bf.bit0;
cout << " binary " << endl;
}
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thanks very much, Pallini! Your code is very useful for me.
In case of trouble, I'll come back to you again.
Many thanks,
Ing LengIeng
Software Developer
|
|
|
|
|
You're welcome.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Hi again!
Now I still have problem concerning reading its content. Can you guide me on that? The following is my code:
BITMAPFILEHEADER bmpHeader;
BITMAPINFO bmpInfo;
FILE *fp = fopen("C:\\test.bmp","rb");
fread((char*)&bmpHeader,sizeof(BITMAPFILEHEADER),1,fp);
fread((char*)&bmpInfo,sizeof(BITMAPINFO),1,fp);
WORD bmpWidth = (WORD)bmpInfo.bmiHeader.biWidth;
WORD bmpHeight = (WORD)bmpInfo.bmiHeader.biHeight;
int counter=0;
fseek(fp,bmpHeader.bfOffBits,SEEK_SET);
BYTE *data = new BYTE[bmpWidth*bmpHeight];
while(!feof(fp))
{
for(int i=0; i<bmpwidth;> {
if(!feof(fp))
{
fread((BYTE*)&data[counter], sizeof(BYTE), 1, fp);
counter++;
}
else
{
break;
}
}
}
fclose(fp);
Here I got an error message saying that "Array index out of bound". What is the correct way of reading it?
Ing LengIeng
Software Developer
|
|
|
|
|
Here again you're doing a mistake on computing the memory required.
For a monochrome bitmap, the size required is bit more elaborate than
(Width * Height ), since the file holds 8 pixels in each byte , and the horizontal line is padded (if I remember well) to have a 32-bit multiple length. Hence
int bytesPerLine = Width / 8;
if (Width % 8) bytesPerLine++;
if (bytesPerLine % 4 ) bytesPerLine += 4 - (bytesPerLine % 4);
int iSize = bytesPerLine * Height;
I hope the above is correct (I haven't tested it). You may verify it comparing the result with the actual size of the file minus the bfOffBits offset.
Two final notes:
- If you allocate memory of a given
size don't trust any other counter (you're using EOF ) while filling it: check always you're not exceeding the allocated size (in your code try to read until the allocated buffer is filled and not until the end of the file: if the file contains more bytes your application crashes). - If you need to read a block, the read it directly, don't read a
byte at time.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thank you very much! I'll check that.
You are very helpful.
Best regards,
Ing LengIeng
Software Developer
|
|
|
|
|
Hi all,
Wat is the difference between closing a dialog by using CDIalog::OnOK() or PostQuitMessage(0).
Can I use both at a time?
Regards
Babu
|
|
|
|
|
Both have different usage. What do you want to do? To close a dialog, why not use EndDialog()? which is straight forward.
OK,. what country just started work for the day ? The ASP.NET forum is flooded with retarded questions. -Christian Graus
Best wishes to Rexx[^]
|
|
|
|
|
Babu@codeproject wrote: Wat is the difference between closing a dialog by using CDIalog::OnOK() or PostQuitMessage(0).
PostQuitMessage will quit your entire application always.
But OnOk will close only the dialog it is called for ( if it is not main dialog)
Also OnOK will call UpdateData().
I hope it helps.
Regards,
Sandip.
|
|
|
|
|
|
|
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
Please Stop posting same question.
You have got answers to previous posts Try and do something based on those answers...
Regards,
Sandip.
|
|
|
|
|
|
Instead, read carefully the posting guidelines (even if they are no more at the top of the forum... ) before posting.
No one here will help you if you:
- post again and again the same question.
- make such stupid and rude replies.
BTW probably *any* idea is a surplus for your brain.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
|
The good answer is:
"Be polite, study harder, check previous answers (see, for instance [^] ), use profitably Google and CodeProject's article search engine."
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|