Sign in to follow this  
Kranar

A simple bmp class

Recommended Posts

Kranar    122
Where can I find a very simple class for C++ that opens a .bmp file, and will allow me to easily see the scan through the pixels of the bitmap in sequential order to see what their values are? I've tried looking but I end up with GDI+ classes, or classes that implement all sorts of complex features, but so far have come up with nothing that allows me to simply check the raw pixel data. Thanks.

Share this post


Link to post
Share on other sites
Telastyn    3777
That's because doing that sort of operation is time consuming and usually unnecissary for games. You might want to look for paint/drawing APIs rather than game APIs since that sort of thing does require pixel data, and doesn't have the time contraints games usually carry with them.

Share this post


Link to post
Share on other sites
Kranar    122
Actually, looking over GDI, it has some useful functions for doing what I want.

Does anyone know, however, how to create a CImage from a CBitmap?

Share this post


Link to post
Share on other sites
Sailorstick    142
I prefer to mess around with the low level stuff :) You can wrap it in class if you want to.
I created this function some time ago to mess around directly with the pixels. bitsOut is a one dimensional array and doesn't need allocating/deallocating. Keep in mind that the width in bytes is always made to be divisible by 4.
But as Telastyn said, the performance is not exactly stellar.


HBITMAP CreateAccessableBitmap(HDC compat, int width, int height, BYTE** bitsOut){
BITMAPINFO binf;
BITMAPINFOHEADER bhdr;
RGBQUAD dummy;
HBITMAP result;

if(bitsOut){
*bitsOut = NULL;
}
bhdr.biBitCount = 24;
bhdr.biClrImportant = 0;
bhdr.biClrUsed = 0;
bhdr.biCompression = BI_RGB;
bhdr.biHeight = -height;
bhdr.biPlanes = 1;
bhdr.biSize = sizeof(BITMAPINFOHEADER);
bhdr.biSizeImage = 0;
bhdr.biWidth = width;
bhdr.biXPelsPerMeter = 0;
bhdr.biYPelsPerMeter = 0;
binf.bmiColors[0] = dummy;
binf.bmiHeader = bhdr;
if(bitsOut){
result = CreateDIBSection(compat, &binf, DIB_RGB_COLORS, (void**)bitsOut, NULL, NULL);
}else{
result = CreateDIBSection(compat, &binf, DIB_RGB_COLORS, NULL, NULL, NULL);
}
return result;
}

Share this post


Link to post
Share on other sites
Will F    1069
You could take a look at SDL it loads BMPs and you can access the pixel data if you so desire. It's also pretty easy to use.

Share this post


Link to post
Share on other sites
Mawr    278
If you want to make your own class, or whatever, that deals with bitmaps, I'd suggest reading up on the two structs BITMAPINFO and BITMAPINFOHEADER. Those once loaded correctly will tell you what you need to do with the data.

Be warned: There is some funnyness with bitmaps. They can have negative height, need to have certain dimensions, and will pad bytes in order to reach them. Be sure to try out reading and displaying on multiple different bmps, before deciding your done with it.

Share this post


Link to post
Share on other sites
xDan    194
I don't seem to be able to post the code here... I keep getting an empty post :-/
I was trying to post this: http://www.xzist.org/files/bitmap.txt

Share this post


Link to post
Share on other sites
Mawr    278
I've read through your code, while I'm far from the best to judge your work, I think it looked pretty solid. I do have a quick question though, and its not criticism, more of a curiosity. You emulated the BITMAPINFO and BITMAPINFOHEADER structs. I'm guessing that is because you didn't want to include the windows libraries that define it. Then later you use the draw function that requires portions of those libraries. Is it because you wanted a quick way to test if it worked correctly?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
allo

to read bmp file you must be define a structure like Image with width and Heigth, the image infos will be find when you start read.

see how i read bmp file very simple, not use MSDN library. Only basic C routine.
i make simple image manipulation: reverse color, you can make your fun very easy.

Note must be put an Image in the directory where your excutable. Use excute with argument to input your bmp file, or change main argument for appropriate use.(give pointer argv="filename.bmp" your image's name, and argc= 3 in your code)

thank,

if u are some pb, send me mail at: assoumemba_AT_HOTMAIL_DOT_COM


#include
#include
#include

/*-------STRUCTURES---------*/
typedef struct {int rows; int cols; unsigned char* data;} sImage;

/*-------PROTOTYPES---------*/
long getImageInfo(FILE*, long, int);
void copyImageInfo(FILE* inputFile, FILE* outputFile);
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors);

int main(int argc, char* argv[])
{
FILE *bmpInput, *bmpOutput;
sImage originalImage;
unsigned char someChar;
unsigned char* pChar;
int nColors; /* BMP number of colors */
long fileSize; /* BMP file size */
int vectorSize; /* BMP vector size */
int r, c; /* r = rows, c = cols */


/* initialize pointer */
someChar = '0';
pChar = &someChar;

if(argc <

Share this post


Link to post
Share on other sites
Endurion    5412
Your compiler probably padded the struct, the BITMAP header structs need to be completely unpadded. Either have the struct be packed to one byte boundaries (compiler dependent) or in case of doubt read the struct members memberwise.

Share this post


Link to post
Share on other sites
ChocoArcher    148
Have you considered using Allegro? It's a library that among other things includes function to load a bitmap into memory (from disk, or created yourself in code), and then you can use the getpixel function to retrieve a single pixel.

Quote:

int getpixel(BITMAP *bmp, int x, int y);

Reads a pixel from point (x, y) in the bitmap. Returns -1 if the point lies outside the bitmap (ignoring the clipping rectangle).



Allegro also allows you to access the width and height of a bitmap by bmp->w and bmp-> h. I'll give you some example code:


#include <allegro.h> //Include the allegro files

void main(void)
{

//initialize program
allegro_init();
install_keyboard(); //Allow keyboard to be used
set_color_depth(16); //16 bit color

//Attempt to set graphics to a window with resolution 800*600
if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0) != 0)
{
allegro_message(allegro_error); //If error, display it as message box
return;
}

BITMAP *myBitmap; //Create a bitmap object
myBitmap = load_bitmap("Picture.bmp", NULL); //Load the bitmap from Picture.bmp and store it in myBitmap object

int pixelColor;

//For each pixel in the bitmap (I'm going vertically by columns here)
for(int x = 0; x < myBitmap->w; x++)
for(int y = 0; y < myBitmap->h; y++)
{
pixelColor = getpixel(myBitmap, x, y);
}

while(!key[KEY_ESC]) //Keep the program running until the user presses escape
{

}

}

Share this post


Link to post
Share on other sites
Oberon_Command    6089
Quote:
Original post by ChocoArcher
Allegro also allows you to access the width and height of a bitmap by bmp->w and bmp-> h. I'll give you some example code:


Here is the same example in SDL, in case anyone's interested:

#include <sdl>

int main (int argc, char *argv[])
{
SDL_Surface *screen, pic;
Uint32 pixel;
Uint8 r,g,b;
int x, y; // set these to whatever you like

SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640,480,32, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);

pic = SDL_LoadBMP("picture.bmp");

SDL_LockSurface (pic);

// these two lines get the red, green, and blue components for a pixel at (x,y) on surface pic
pixel = pic->pixels + y * pic->pitch + x * 32;
SDL_GetRGB(pixel, pic->format, &r, &g, &b);

SDL_UnlockSurface( pic);
SDL_FreeSurface(pic); // have to remember this, otherwise there's a memory leak - this is why Cone3D's code is bad
SDL_Quit();
return 0;
}



Edit: The two lines that actually read the pixel could be placed into a function like so:


Uint32 getPixel(SDL_Surface *surf, int x, int y, Uint8 *r, Uint8 *g, Uint8 *b)
{
Uint32 pixel;
pixel = surf->pixels + y * surf->pitch + x * 32; // here we get the actual pixel data
SDL_GetRGB(pixel, surf->format, &r, &g, &b); // here we send the colour components back

return pixel; // return the original data so that the user can play with it if he/she wants to
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this