Archived

This topic is now archived and is closed to further replies.

Help me understand bitmap handles.

This topic is 5129 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

For a while now I’ve been trying to create a program that can load ppm files and bitmap files, and then save them to ppm files. I have 2 problems that I just can’t figure out and I think it is something with bitmap handles that I don’t understand. It loads bitmaps themselves perfectly, but when it tries to load and save to a ppm files it has the following problems: 1) It saves the colors of the loaded ppm files wrong, but it displays them as if they were loaded correctly. For example. I have a stripped ppm file where the coloring order from top to bottom is RED, GREEN, BLUE. However, if I load it to my program, it displays it as BLUE, GREEN, RED. Then when I load a bitmap, it displays it perfectly. However, when I save that bitmap to a ppm file and then load that ppm file, it appears to have loaded and saved correctly, but when I load the file on notepad, it shows that it in fact did NOT save or load correctly. So, in conclusion, it saves it wrong, but the way it loads it is wrong as well, which makes it look like it everything is ok. 2) As I said earlier, it displays the bitmap correctly, but when I save that bitmap to a ppm file and then load it, it has a couple of problems with the dimensions. If the height of the bitmap is equal to the width, then nothing is wrong(other than the coloring); if the width is greater than height, it ignores what would normally be displayed on the section with the difference between the width and height and mirrors the beginning creating sort of a wrap around effect. If the height is greater than the width, it returns an error. Here is some of the relevant code I used. Please help me figure this out:
//creates a pixel from the blue, green, and red values

#define makePixel(b,g,r) ((b%256)+((g%256)<<8)+((r%256)<<16))

//parses a color into blue green and red values

void ParseColor(COLORREF color, int &b,int &g, int &r)
{

r=(color)>>16;
g=(color-(r<<16))>>8;
b=color-(r<<16)-(g<<8);

}

//my structure that holds the information about the bitmap handle 


struct SBitmap{
	int height;
	int width;
	HBITMAP bitmap;
	HBITMAP oldbitmap;
	HDC		Dbitmap;
};
struct pixel
{
	 int red;
	 int green;
	 int blue;

};

//class that holds my image information

class PPM_MAP{

private:
	pixel *data;
	int height;
	int width;
	public :
	//PPM_MAP();

	void Save(char *file);
	void LoadFromBitmap(SBitmap mybit);
	SBitmap LoadToBitmap(HWND hwnd);
	~PPM_MAP();
	void LoadPPM(char *file);

};

//this function loads the information from the Sbitmap class to the PPM_MAP class.

void PPM_MAP::LoadFromBitmap(SBitmap mybit)
{


	
	data = new pixel[mybit.height * mybit.width];

	height=mybit.height;
	width=mybit.width;
	
	for(int y=0;y<height;y++)
	{
		
		for(int x=0;x<width;x++)
		{
			ParseColor(GetPixel(mybit.Dbitmap,x,y),
						data[y*height+x].blue,
						data[y*height+x].green,
						data[y*height+x].red);
			
		}
	}

}

//this function loads a ppm file to the PPM_MAP class

void PPM_MAP::LoadPPM(char *file)
{
	FILE *fin;

	fin=fopen(file,"r");

	char header[100];
	char ch;
	int max;

	fscanf(fin,"%[^\n] ",header);

	fscanf(fin,"%c",&ch);
	
	while(ch =='#')
	{
		fscanf(fin,"%[^\n] ",header);

		fscanf(fin,"%c",&ch);
	}
	

	ungetc(ch,fin);

	fscanf(fin, "%i %i",&width,&height);
	fscanf(fin,"%i",&max);
	
	
	data= new pixel[width*height];
	
	for(int y=0;y<height;y++)
		{
			for(int x=0;x<width;x++)
			{
				fscanf(fin,"%i",&data[y*height+x].red);
				fscanf(fin,"%i",&data[y*height+x].green);
				fscanf(fin,"%i",&data[y*height+x].blue);
			}
		}


	fclose(fin);

}


//this function creates a bitmap and loads the information from the PPM_MAP class 

// to a Sbitmap class

SBitmap PPM_MAP::LoadToBitmap(HWND hwnd)
{
	 HDC hdcWindow = GetDC(hwnd);
        
	    SBitmap mybit;
		COLORREF temp;
		
	    mybit.Dbitmap = CreateCompatibleDC(hdcWindow);

		
		mybit.bitmap=CreateCompatibleBitmap(hdcWindow,width,height);
		
	    // select the image into the memory dc

	    SelectObject(mybit.Dbitmap,mybit.bitmap);
	
		
		for(int y=0;y<height;y++)
		{
			for(int x=0;x<width;x++)
			{
				temp=makePixel(data[y*height+x].blue,
							   data[y*height+x].green,
							   data[y*height+x].red);


				SetPixel(mybit.Dbitmap,x,y, temp);
			}
		}


	    mybit.width = width;
	    mybit.height = height;


      // release the DC obtained

      ReleaseDC(hwnd, hdcWindow);

	  return mybit;

}




//this is the function that saves the ppm file from my PPM_MAP class

void PPM_MAP::Save(char *file)
{
	FILE *fout;

	fout = fopen(file,"w");

	fprintf(fout,"P3\n");
	fprintf(fout,"%i %i\n",width,height);
	fprintf(fout,"256\n");

	for(int y=0;y<height;y++)
	{
		for(int x=0;x<width;x++)
		{
			fprintf(fout,"%i ",data[height*y+x].red);
			fprintf(fout,"%i ",data[height*y+x].green);
			fprintf(fout,"%i ",data[height*y+x].blue);

			fprintf(fout," ");
		}
		fprintf(fout,"\n");
	}
	fclose(fout);
}

[\source]
[edited by - manastone on November 30, 2003 4:46:03 PM]

Share this post


Link to post
Share on other sites
Windows bitmaps use Blue Green Red order which could be why your data shows up correctly, but it is still strange that it still does so after loading and saving.

You probably obtained the ppm file by loading a bitmap which would explain why everything is saved and loaded in such a way that everything shows up the right way.




[ Galactic Conquest | Bananas | My dead site | www.sgi.com | Goegel ]

Share this post


Link to post
Share on other sites
It sounds like you have the color reversed (bgr instead of rgb). I always thought that DIB''s were stored in rgb (r>>0|g>>8|b>>16), but I don''t really know off hand. Anyways, the way you did parsecolor confused me. It''s much easier to understand, IMO, if you did something like this:

void parsecolor(colorref color,int& r,int& g,int& b)
{
b=(int)((unsigned char)color);
g=(int)((unsigned char)(color>>8));
r=(int)((unsigned char)(color>>16));
}



--------
"Hey, what about those baggy pants you kids are wearin'' these days? Aren''t they hip and cool and poppin'' fresh?"-Peter Griffin
"Everytime I see an M followed by a dollar sign I just say "oh god" and go to the next post."-Neurokaotix
the D programming language

Share this post


Link to post
Share on other sites
I thought windows did things B G R. I know PPM files save things R G B, and I made up for that, or at least I think I did. I used my makePixel macro when creating a color for the background for a simple Direct X windowed app, so I''m pretty sure that is not the problem. Do you have any idea what could be wrong with the dimensions though?

Share this post


Link to post
Share on other sites