|
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
|
|
|
|
|
This is a bitwise left-shift operation which is equivalent to
m_nPaletteEntries = pow(2, m_pBIH->biBitCount); What are shift operators in C++?[^]
This trick is used quite often, since a bitwise shift operation is way quicker than the pow() method, which is rather intense on processing time.
Edit: here's an interesting list of useful bitwise tricks:
Bit Twiddling Hacks[^]
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
It's not pow, it's multiply by 2.
|
|
|
|
|
For a left-shift by a single bit, yes, a multiplication by 2.
But a left-shift by n bits, in the end, is the same as a multiplication by 2 to the power of n; since original value is 1, this leads to 2 to the power of n. Or am I missing something?
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
I found myself thinking about this when I woke up this morning and you are, of course, quite correct.
|
|
|
|
|
Richard I appreciate your willingness to help
|
|
|
|
|
fearless_ wrote: Would you mind helping me further? I loaded the bitmap, however when I check the values from the array into which the bitmap is loaded they show up as 0 (null).
1. How did you load the bitmap?
2. How did you "check the values from the array into which the bitmap is loaded"?
3. Did you try to open this bitmap with some graphic editor/viewer?
|
|
|
|
|
Victor thanks for offering to help, take a look at my reply to Richard
|
|
|
|
|
You are messing around with stuff you do not have to do on Windows and there is no advantage in doing what you are doing other than learning.
You can load a bitmap with one line of code using the API LoadBitmap()
LoadBitmapA function (winuser.h) - Win32 apps | Microsoft Docs[^]
One line of code will load it for you and it doesn't care what the bitmap format is.
HBITMAP MyBmp = LoadBitmap(0, "Yourbitmapname.bmp");
Once you have a HBITMAP (handle to a bitmap) in Windows you can basically do everything with it.
If you want the details from the bitmap once you have it loaded you just ask windows to extract them for you
So with my handle above I can extract the header with 2 lines of code the 3rd line is just to throw the details out (it assumes you are doing a console app).
BITMAP bm;
GetObject(MyBmp, sizeof(bm), &bm);
printf("Bitmap is wth: %u ht: %u bitdepth: %u\r\n", bm.bmWidth, bm.bmHeight, bm.bmBitsPixel);
So I can load the bitmap and extract the header with 3 lines in absolute safety.
If you are messing around with the actual header etc in Windows you are doing it all wrong
The only time you might play with a BMP file header is writing a BMP in a specific format.
That is why there is no need for libraries on Windows to handle bitmaps. Now JPEGS are a little trickier it's about 20 lines of code to get windows to load one of those most of the issue the filename has to be in UNICODE. Let me know if you need to know how to do it.
In vino veritas
modified 12-Mar-20 11:48am.
|
|
|
|
|
leon de boer wrote: One line of code will load it for you and it doesn't care what the bitmap format is.
HBITMAP MyBmp = LoadBitmap(0, "Yourbitmapname.bmp");
You probaly meant the [LoadImageA function (winuser.h) - Win32 apps | Microsoft Docs](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadimagea) function that can load the bitmap from the file.
LoadBitmap only loads the bitmap from resources.
|
|
|
|
|
Yep sorry needed more coffee last night, clearly
In vino veritas
|
|
|
|
|
I`m learning how to work with bitmaps. Could someone explain what`s a palette when reading from a bitmap
|
|
|
|
|
A palette is a collection of indexed colours. In a bitmap using a palette, instead of refering to a colour by specifying its raw value, it is specified by its index in the palette instead.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
Thanks phil.o, so this palette is used as a compression method/way to save space? Is this feature used at all? How do people usually store data to bmps with or without using a palette?
|
|
|
|
|
Exactly, this allows to save space by 1) only referencing used colours in the palette 2) using colour references instead of raw values.
This feature is used in .gif files, as well as in icons, IIRC. It is not used in .bmp files, which store colour information uncompressed. It may be used in other formats as well.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
Unfortunately (I would call it that, because it's a mess) BMP files are in theory quite general, with tons of annoying features being piled onto it. Using any of those features results in a BMP file that a lot of software can't read (or reads differently than intended) because almost everyone treats BMP as only 24bit-uncompressed with no fancy extras. But anyway, in theory, a BMP file can indicate that it has 8 or fewer bits per pixel and then it must have a color table aka palette. The pixel data can even be compressed then.
|
|
|
|
|
Thanks for the update. I never had to work with bmps other than plain 24 bpp (or 8 bpp for b/w) uncompressed data.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
thanks for your help. So biBitCount less than 9 it`s no longer what you would consider a bitmap
|
|
|
|
|
Yes I would still consider it as a bitmap.
I was specifically talking about .bmp files. The general notion of bitmap is something different.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
my bad, I meant it`s no longer a .bmp
|
|
|
|
|
But apparently I'd be wrong, as harold aptroot told, .bmp format is way more generic than that.
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
|
It is rare but even 24bit and 32bit bitmaps can have palettes, you do it if you want something like millions of shades of blue for example when printing an ocean scene.
If you look at the structure of the BitmapFileInfo header .. look at the second last entry that is how you know how many palette colours there are ... the last entry tells you how many are important.
bitmapinfoheader[^]
It is spelled out very clearly ...
If biClrUsed is zero, the array contains the maximum number of colors for the given bitdepth
You assume a 24bit or 32bit bitmap have no palette at your own risk.
In vino veritas
|
|
|
|
|
for a short test in my class, we had to write code about pigs that allowed the user to enter information about a set of pigs (e.g. the pigs' names, breed, weight, gender, etc.). We were to create a class called pigs that would be able to hold the pigs' information. There was nothing wrong with the class itself, the problem I'm having is actually in the main function.
cout << "Enter the pig gender (\'m\'/\'f\')(if not press \'enter\' for none): ";
cin.getline(pigGender, 10);
if(pigGender != "\n")
{
while(pigGender != "m" && pigGender != "f")
{
cout << "Invalid gender, please enter a valid gender m or f(if not press \'Enter\'): ";
cin.getline(pigGender, 10);
if(pigGender != "\n")
{
gender = pigGender[0];
}
else
{
gender = ' ';
break;
}
}
pigs[i].SetPigGender(gender);
}
The piece of code above, shows how I'm trying to obtain the pig's gender from the user. I made it so that if the user doesn't know the gender, they can just hit enter to move on (as I did with other features that worked fine). The problem is that when you hit enter, the pigGender string doesn't seem to take the newline character. Also, I understand how the getline function works (takes in a newline and stops), hence I believe when you hit enter, the getline will take in the newline and stop, but here it does not seem to take it in at all. I also made it so that if the user enters a wrong letter (not m or f), then they can still hit enter if they do not know. The commented out codes are checks I implemented to see exactly what was in pigGender. When I enter a charcter that is not a newline it will go to the if branch and dislpay my error message, however, when I hit only enter, it still goes through that if branch instead of the else branch. the checks i commented out show me which branch I am in and the charcter in the pigGender string, and when I hit enter for the newline, there seems to be nothing in the pigGender string. What seems even more bizarre, is that the following code is very similar to what I did above (I actually copied and pasted it and made some changes to make the one above) and it works perfectly.
cout << "Enter the pig weight(if not press \'Enter\'): ";
cin.getline(weight, 10);
if(weight != "\n")
{
float pigWeight = atof(weight);
while(pigWeight < 0)
{
cout << endl;
cout << "Invalid weight, please enter a valid weight(if not press \'Enter\'): ";
cin.getline(weight, 10);
if(weight != "\n")
{
pigWeight = atof(weight);
}
else
{
pigWeight = 0;
}
}
pigs[i].SetPigWeight(pigWeight);
}
Is there something I'm just not seeing here, because I have been looking at this code since yesterday and have tried a bunch of stuff to fix it but can't. Of course, I do know of many other ways to tackle this problem (like comparing string size instead), but I started with this and its really bugging me that it does not work, so I just want to figure it out just so I can know. If you can help me understand, please respond, I really want to figure this thing out, thank you!
|
|
|
|
|
iostream::getline() strips the trailing delimiter from input. That means that when you hit return only, the string is empty (e.g = "" ).
You also have an error in all your string comparisons:
if(weight != "\n") is always true (this actually compares the address of weight to the address of the static object "\n" . To compare objects of type char * (or char[] ), you must use strcmp() . In this case, since you are just interested to see if the only char in the string is '\n' you could say
if(weight[0] != '\n') (note that this still won't work because iostream::getline() strips the newline delimiter from the input.
It only looks like the weight is being skipped. As explained above the comparison is always true, so the code block following the comparison is always executed. What is happening is that
pigweight = atof(weight) evaluates with weight = "" , which evaluates to zero, so it only seems like the code block was skipped. If you were to change the code to, say
if(weight != "\n") {
cerr << "checking weight from user\n";
}
You would always see the "checking weight from user" message, whether you hit return or not.
|
|
|
|
|