12 Replies - 1863 Views - Last Post: 07 May 2007 - 03:35 PM Rate Topic: -----

#1 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

writing bitmap

Posted 04 May 2007 - 04:54 PM

Hi,
I'm trying to output a plain red bitmap using only the C++ stl (so I can't use windows.h and it's functions, found in the tutorial). How would I go about doing this? At the moment, I've imported a (working) bitmap header file. I read this file in, and then output it to a new file using streams. The new file then ends up being a 700 x 700 bitmap file, like it should be. However, when I open it in windows picture viewer, it says drawing failed. I assume this is because I need to append some more information on to the end of the header. What would I append to the end of it in order to make it plain red?
Thanks

This post has been edited by unsigned user;: 04 May 2007 - 04:55 PM


Is This A Good Question/Topic? 0
  • +

Replies To: writing bitmap

#2 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 05 May 2007 - 06:27 PM

Well this depends on your header doesn't it. How many BBP (bits per pixel) -- lets assume 24 (8 is really easier but the tutorial was in 24).

If you have a 24 bit bitmap then each pixel is 3 bytes. BGR (Blue, Green, Red). so the information you will want to write is 00 00 FF.

So basicly you write 00 00 FF 700 times per 700 rows.

Bitmaps normally do this neat little trick where each row is a multiple of 4. So say My bmp was 271 pixels across... 271 x 3 = 813 bytes per row which is not a multiple of 4... but 816 is and so there would be an extra padding of 3 bytes at the end of each row.

I ussualy use something like:
rowlen = ((rowlen % 4) ? (rowlen/4 +1 ) * 4 : rowlen);
Which will move up to the next integral number if rowlen is not an integral number, else it remains the same.
Was This Post Helpful? 0
  • +
  • -

#3 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 05 May 2007 - 06:48 PM

Thanks for the reply. How would I actually do this in code? At the moment, I've got this:
#include <fstream>
#include <iostream>

using namespace std;


struct rgb {
char b;
char g;
char r;


};

rgb *pixel = new rgb[700 * 700];



int main()
{
char fileName[54];
char buffer[255];


ofstream fout("bitmap.bmp", ios::app);

ifstream fin("bmpH.hdr");
char ch;

while(fin.get(ch)) //write out the header to the file
{
fout << ch;
}


//scroll through each pixel
for (int j=(699); j >=0; j--){
for (int l=0; l<700; l++){


int i = l+(j*700);

pixel[i].b =  0x00;
pixel[i].g =  0x00;
pixel[i].r =   0xFF;

fout << pixel;


}
}




fin.close();


return 0;


}



It outputs a large (around 55mb) bitmap. However, it's come out strangely. What am I doing wrong?
Thanks again for the help.

This post has been edited by unsigned user;: 06 May 2007 - 04:03 PM

Was This Post Helpful? 0
  • +
  • -

#4 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 05 May 2007 - 07:43 PM

don't suppose you could make your program output a 32x32 bmp or something small so I could look over your header info.

What seems to be happening is that the data is split into planes.
Was This Post Helpful? 0
  • +
  • -

#5 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 05 May 2007 - 07:55 PM

I can't edit the HDR file. It's been given as-is and I have to use it, so it produces the 700x700 automatically when I read it in and write it out. I believe it's 54 bytes of header info.

EDIT: I think I may have solved it, but I don't know why it works. I changed char fileName[54] to fileName[5] and ran it. The program outputted a plain BMP file like it should. I then changed it back to fileName[54] and it still outputs it in all red. Very strange. Thanks for the help!

This post has been edited by unsigned user;: 05 May 2007 - 07:58 PM

Was This Post Helpful? 0
  • +
  • -

#6 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 05 May 2007 - 08:01 PM

There are a couple of notes. First of all using the struct to hold the rgb data is not the best idea. Well its ok, but you don't want to just write the struct.

The reason is that compilers will often pad structures to make them allign in memory. (you can check this by using sizeof() to see if you get 3).

Second of all the Header info is not all that hard to get. You can copy it right out of the windows.h file, or find it (all over the net) at wotsit.org.
Was This Post Helpful? 0
  • +
  • -

#7 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 06 May 2007 - 10:42 AM

What would be the best way to hold the RGB data? I used sizeOf, and I got 3 as the output. However, I've run into another problem. It seems that I can't access an individual pixel. How would I go about accessing an individual pixel? Would it be best to use a 2D vector, or is there a way I can extend my current method in order to access specific pixels?
Thanks for the help :)
Was This Post Helpful? 0
  • +
  • -

#8 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 06 May 2007 - 07:06 PM

if you are holding your data in a linear array then you can access a given pixel (x, y) with a formula such as
index = x + y * 700;
Then since you are using a struct you can then use:
rgb[index].r = 0xFF; to access the red portion of that pixel etc...

The reason I warned against holding the data in a struct is that when you write the data to the file you have to ensure that only the data you MEAN to write gets written to the file. As I said some (not yours obviously) compilers will pad structures to access data more effecently (some processors don't deal well with anything less than thier word size so accessing 1 byte at a time can cause unwanted overhead). In this instance it probably would have been better if I had not mentioned anything at all as you compiler does what is expected.
Was This Post Helpful? 0
  • +
  • -

#9 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 06 May 2007 - 08:00 PM

I tried doing this
#include <fstream>
#include <iostream>
#include <vector>



using namespace std;


struct rgb { 

char b;
char g;
char r;


};


rgb *pixel = new rgb[700 * 700]; 





int main()
{
	char fileName[54];
	char buffer[255];
	

	ofstream fout("bitmap.bmp", ios::app);
	
	ifstream fin("bmpH.hdr");
	char ch;
	
	while(fin.get(ch))	 
	{
						   fout << ch;
	
						   
	 }
		  
for (int j=(699); j >=0; j--){ 
for (int l=0; l<700; l++){


int i = j+(((700-1)-l)*700); // if you have a vertically flipped image





pixel[i].b = 0xFF; 
pixel[i].g = 0xFF;
pixel[i].r = 0xFF;

 fout << pixel[i].b;
 fout << pixel[i].g;
 fout << pixel[i].r;





}
}



int i = 200 + 200 * 700;

pixel[i].b = 0x00; 
pixel[i].g = 0x00;
pixel[i].r = 0x00;

 fout << pixel[i].b;
 fout << pixel[i].g;
 fout << pixel[i].r;

	
		 


	fout.close();
	fin.close();
	
  
	
   system("PAUSE");
   remove("bitmap.bmp");
	return 0;
	
}




but it keeps coming up with a plain white bitmap with no black pixel. I'm trying to fill the background in one colour, and then draw on certain pixels (in this case, the pixel at 200x200).
Thanks again for the help.

edit: could it be anything to do with how I'm opening fout? I'm setting it in append mode.

This post has been edited by unsigned user;: 06 May 2007 - 08:02 PM

Was This Post Helpful? 0
  • +
  • -

#10 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 06 May 2007 - 08:56 PM

Well yes... the append mode is probably not the mode to be in. You will want to start fresh with each new attempt. Append puts the pointer to the very back.

BTW, sorrry I didn't think about this eariler, but remeber than you scan lines are upside down (bottom first). So the formula index=x+700*y; is not exactly right to get pixel (200, 200)... that would be (200, 500) I belive.
Was This Post Helpful? 0
  • +
  • -

#11 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 07 May 2007 - 01:59 PM

If I don't append it, wouldn't that overwrite the whole bitmap, which has the header file in it?
Was This Post Helpful? 0
  • +
  • -

#12 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: writing bitmap

Posted 07 May 2007 - 03:29 PM

well... yes... but aren't you getting the headder form another file?

I thought that is what
ifstream fin("bmpH.hdr");
	char ch;
	
	while(fin.get(ch))	
	{
						   fout << ch;
	
						  
	 }

was doing. Copying the header to the file.
Was This Post Helpful? 0
  • +
  • -

#13 unsigned user;  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 29
  • Joined: 28-April 07

Re: writing bitmap

Posted 07 May 2007 - 03:35 PM

EDIT: Thanks NickDMax for all the help. I've finally managed to crack it and it all seems to be working fine. Now to get the main project finished :D. Thanks again. I appreciate all your help.

This post has been edited by unsigned user;: 07 May 2007 - 04:19 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1