Click here to Skip to main content
15,884,986 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I tried to do it myself. Here my code with Dev-C++ :
C++
#include <iostream>
#include <fstream>
#include <glut.h>
using namespace std;
#pragma pack(push, 2 )
	struct BitmapHeader // 14 byte
	{
		short sigNature;			
		unsigned long fileSize;
		long reserved;
		long dataOffset;
	};
	struct BitmapInfoheader // 40 byte
	{
		unsigned long infoSize; 
		unsigned long width;    
		unsigned long heigh;	
		unsigned short planes;	
		unsigned short bitCount;	
		unsigned long compression; 
		unsigned long imageSize;	
		long xPixelsPerMeter;	
		long yPixelsPerMeter;	
		unsigned long clrUsed;  
		unsigned long clrImportant; 
	};
#pragma pack(pop)

//--------------------------------------

	struct	BitmapHeader bmheader;
	struct	BitmapInfoheader bmInfo;
	char* colorPlane;
	char* imgData;

int loadBmImg()
{
	char tt[20] ;
	ifstream sf;
	char word;
	cout<<"Input filename of image : ";
	cin.getline(tt,20);
	sf.open(tt,ios::in|ios::binary);

	if(sf.bad())
	{
		 cout<<"Can't open the image!";
		 return 0;
	}
		sf.read((char*)&bmheader,sizeof(bmheader));
		sf.read((char*)&bmInfo,sizeof(bmInfo));
		colorPlane = new char[4*256]; //it's simple bitCount=8
		imgData = new char[bmInfo.imageSize];
		sf.read(colorPlane,4*256);
		sf.read(imgData,bmInfo.imageSize);
	sf.close();
}

//---------------------------------

void init() 
{
    glClearColor (0.0, 0.0, 0.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
    glOrtho(0, bmInfo.width, 0, bmInfo.heigh, -1.0, 1.0);

}

void drawBmImage(void)
{
	unsigned char r,g,b;
	GLint R,G,B;
	unsigned long int index;
	glBegin (GL_POINTS);
   for(int j=0; j<bmInfo.heigh; j++)
   		for(int i=0;i<bmInfo.width; i++)
   		{
   			index = (unsigned long)imgData[j*bmInfo.width+i];
   			r = colorPlane[4*index];
   			g = colorPlane[4*index+1];
   			b = colorPlane[4*index+2];
			R = (unsigned short)r;
   			G = (unsigned short)g;
   			B = (unsigned short)b;
   			glColor3ub(R,G,B);
   			glVertex3i(i,j,0);
   		}
   	glEnd();	
}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   drawBmImage();
   glFlush ();
}


int main(int argc, char** argv)
{
   loadBmImg();
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (bmInfo.width, bmInfo.heigh); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("OpenGL");
   init ();
   glutDisplayFunc(display); 
   glutMainLoop();
   return 0;
}


But the result here
It seems I get a mistake with the colors. How can I fix them ?
Posted
Updated 31-Jan-14 7:31am
v3
Comments
enhzflep 31-Jan-14 15:51pm    
The problem that you appear to be facing is a common one - it comes down to the order that the data is stored in (a) memory and (b) on disk.
The problem is that while you've expected RGB ordering, what you actually get is BGR ordering - that is to say, the red and blue channels have been swapped. I can't remember if it's memory or disk that stores as RGB - it doesn't matter. The solution is very easy, you may either:

1) Swap the r & b values
-------------------------
r = colorPlane[4*index];
g = colorPlane[4*index+1];
b = colorPlane[4*index+2];


becomes

r = colorPlane[4*index+2];
g = colorPlane[4*index+1];
b = colorPlane[4*index+0];



or

glColor3ub(R,G,B); becomes glColor3ub(B,G,R);

Do note however, this mostly fixes the image although there are still colour artefacts - the whitish areas of the image are quite magenta. There seems to be an issue with the pallette - perhaps the image has been re-quantized.

In any case, the image is orange rather than blue because of the swapped R and B components.
Toan Pham Anh 31-Jan-14 17:07pm    
Thank you! ,but why they swap R and B ? Maybe it read 4 bytes per times for RGB ? How could I display images as applications on my computer?
SoMad 31-Jan-14 19:26pm    
You should have posted this as a solution.

Soren Madsen
Sergey Alexandrovich Kryukov 31-Jan-14 20:15pm    
The question is: why bothering? 256-mode is really bad, was actual for a while, when video cards were a very limiting factor...
—SA

1 solution

The first was already suggested:

C++
b = colorPlane[4*index];
g = colorPlane[4*index+1];
r = colorPlane[4*index+2];


Some more improvements for color and compatiblity are here:

C++
sf.seekg(bmheader.dataOffset); // perform seek

imgData = new BYTE[bmInfo.imageSize];
sf.read((char*)imgData,bmInfo.imageSize);


and finally to be independent from width this is important:

C++
unsigned long stride = ((((bmInfo.width * bmInfo.bitCount) + 31) & ~31) >> 3);

for(int j=0; j<bmInfo.heigh; j++)
     for(int i=0;i<bmInfo.width; i++)
     {
         index = (unsigned long)imgData[stride*j + i];
         ... 
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900