Help with manually creating a BMP image

Thread Solved
Reply

Join Date: Jan 2009
Posts: 6
Reputation: BMPaul is an unknown quantity at this point 
Solved Threads: 0
BMPaul BMPaul is offline Offline
Newbie Poster

Help with manually creating a BMP image

 
0
  #1
Jan 2nd, 2009
Hello, im a noob with C++ at the moment and Im trying to create a BMP image from pixel data stored in a array. Everything seems to work except that when i look at the file generated in a hex editor i get an extra '00 00' in between the BM identifier and the bytes reserved for the file size. It is as though the member short BM within the bmp_header struct is taking 4 bytes where i think i it is suppose to take 2 bytes. Could someone please explain why this is happening. Thanks in advance. (there are probably much more efficient ways of doing this but this is the way i want 2 do it at the moment)


Template is from http://en.wikipedia.org/wiki/BMP_file_format (the 2 by 2 pixel example)

  1. #include <fstream>
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. #define w_in_pix 2
  6. #define h_in_pix 2
  7. short padding = 0x0000;
  8.  
  9.  
  10. struct bmp_header
  11. {
  12. short BM;
  13. long size_of_file;
  14. long reserve;
  15. long offset_of_pixle_data;
  16. long size_of_header;
  17. long width;
  18. long hight;
  19. short num_of_colour_plane;
  20. short num_of_bit_per_pix;
  21. long compression;
  22. long size_of_pix_data;
  23. long h_resolution;
  24. long v_resolution;
  25. long num_of_colour_in_palette;
  26. long important_colours;
  27.  
  28. }
  29. HEADER;
  30.  
  31. // pix array ///////////////////////////////////////////////////////////////////////////
  32. // L to R //
  33. char BGR [12] = {
  34. 0xFF,0x00,0x00, 0x00,0xFF,0x00,
  35. 0x00,0x00,0xFF, 0xFF,0xFF,0xFF};
  36. ////////////////////////////////////////////////////////////////////////////////////////
  37.  
  38. int main()
  39. {
  40. HEADER.BM = 0x4d42;
  41. HEADER.size_of_file = sizeof(HEADER) + sizeof(BGR) + sizeof(padding) * h_in_pix;
  42. HEADER.reserve = 0000;
  43. HEADER.offset_of_pixle_data = 54;
  44. HEADER.size_of_header = 40;
  45. HEADER.width = w_in_pix;
  46. HEADER.hight = h_in_pix;
  47. HEADER.num_of_colour_plane = 1;
  48. HEADER.num_of_bit_per_pix = 24;
  49. HEADER.compression = 0;
  50. HEADER.size_of_pix_data = sizeof(BGR) + sizeof(padding) * h_in_pix;
  51. HEADER.h_resolution = 2835;
  52. HEADER.v_resolution = 2835;
  53. HEADER.num_of_colour_in_palette = 0;
  54. HEADER.important_colours = 0;
  55.  
  56. // write BMP Header ////////////////////////////////////////////////////////////////
  57. ofstream file;
  58. file.open ("test.bmp", ios::out | ios::trunc | ios::binary);
  59. file.write ((char*)(&HEADER), sizeof(HEADER));
  60. ////////////////////////////////////////////////////////////////////////////////////
  61. // write BMP data //////////////////////////////////////////////////////////////////
  62. //file.write ((char*)(&BGR[0]),1);
  63.  
  64.  
  65. int position = w_in_pix * h_in_pix * 3;
  66. while (position != 0)
  67. {
  68. for (int n = 0; n != w_in_pix * 3; n++)
  69. {
  70. file.write ((char*)(&BGR[position - w_in_pix * 3 + n]), 1);
  71. }
  72. file.write ((char*)(&padding), 2);
  73. position = position - w_in_pix * 3;
  74. }
  75.  
  76.  
  77. }
Reply With Quote Quick reply to this message  
Join Date: Dec 2005
Posts: 5,851
Reputation: Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute 
Solved Threads: 749
Team Colleague
Salem's Avatar
Salem Salem is offline Offline
Void main'ers are DOOMed

Re: Help with manually creating a BMP image

 
0
  #2
Jan 2nd, 2009
The short answer is padding and alignment.

> short BM;
> long size_of_file;
To ensure efficient access to size_of_file, the compiler inserts a pair of padding bytes after BM.

The common way to "fix" this is to use something like #pragma pack(1) , but there is no standard way to tell a compiler how to do this (or indeed how well your request for packing the struct will be met).

Also look up "endian-ess"

Unfortunately, the only good long-term answer (which is pretty horrible) is to read/write bytes one at a time, and assign them to the struct in the correct order.
Reply With Quote Quick reply to this message  
Join Date: Jan 2009
Posts: 6
Reputation: BMPaul is an unknown quantity at this point 
Solved Threads: 0
BMPaul BMPaul is offline Offline
Newbie Poster

Re: Help with manually creating a BMP image

 
0
  #3
Jan 2nd, 2009
Thanks 4 your help. Ill experiment with what you told me today
Reply With Quote Quick reply to this message  
Join Date: Jul 2008
Posts: 2,001
Reputation: ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of ArkM has much to be proud of 
Solved Threads: 343
ArkM's Avatar
ArkM ArkM is offline Offline
Postaholic

Re: Help with manually creating a BMP image

 
0
  #4
Jan 2nd, 2009
Yet another common and portable approach: use ordinar structures to create BMP info then pack them into the final char buffer (use memcpy(buffer+offset,&member,sizeof member), move offset forward and so on). Of course, it's possible to write data to a file stream directly (no need in current write pos forwarding).
Add some syntax sugar, for example:
  1. struct bmp_header
  2. {
  3. short BM;
  4. long size_of_file;
  5. long reserve;
  6. long offset_of_pixle_data;
  7. long size_of_header;
  8. long width;
  9. long hight;
  10. short num_of_colour_plane;
  11. short num_of_bit_per_pix;
  12. long compression;
  13. long size_of_pix_data;
  14. long h_resolution;
  15. long v_resolution;
  16. long num_of_colour_in_palette;
  17. long important_colours;
  18. void* pack(void* pbuf) {
  19. char* p = (char*)pbuf;
  20. int i = 0;
  21. # define PACK(member) {memcpy(p+i,&member,sizeof member);i+=sizeof member;}
  22. PACK(BM)
  23. PACK(size_of_file)
  24. ...
  25. PACK(important_colours)
  26. # undef PACK
  27. return pbuf;
  28. }
  29.  
  30. }
  31. HEADER;
  32. ...
  33. HEADER.pack(buffer)
A nasty thing but it works
Reply With Quote Quick reply to this message  
Join Date: Apr 2008
Posts: 670
Reputation: Freaky_Chris is a jewel in the rough Freaky_Chris is a jewel in the rough Freaky_Chris is a jewel in the rough 
Solved Threads: 113
Freaky_Chris's Avatar
Freaky_Chris Freaky_Chris is offline Offline
Practically a Master Poster

Re: Help with manually creating a BMP image

 
0
  #5
Jan 3rd, 2009
Can i suggest you store the value of BM outside of the structure and store it in a char array of size 2 then write each one to the file before calling write() on the structure.

Chris
Knowledge is power -- But experience is everything
Reply With Quote Quick reply to this message  
Join Date: Jan 2009
Posts: 6
Reputation: BMPaul is an unknown quantity at this point 
Solved Threads: 0
BMPaul BMPaul is offline Offline
Newbie Poster

Re: Help with manually creating a BMP image

 
0
  #6
Jan 3rd, 2009
I did what freaky_chris suggested and created the value of BM outside of the bmp_header struct and it seems to work. Final code is now

  1. #include <fstream>
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. #define w_in_pix 2
  6. #define h_in_pix 2
  7. short padding = 0x0000;
  8. short BM = 0x4d42;
  9.  
  10. struct bmp_header
  11. {
  12.  
  13. long size_of_file;
  14. long reserve;
  15. long offset_of_pixle_data;
  16. long size_of_header;
  17. long width;
  18. long hight;
  19. short num_of_colour_plane;
  20. short num_of_bit_per_pix;
  21. long compression;
  22. long size_of_pix_data;
  23. long h_resolution;
  24. long v_resolution;
  25. long num_of_colour_in_palette;
  26. long important_colours;
  27.  
  28. }
  29. HEADER;
  30.  
  31. // pix array ///////////////////////////////////////////////////////////////////////////
  32. // L to R //
  33. char BGR [12] = {
  34. 0xFF,0x00,0x00, 0x00,0xFF,0x00,
  35. 0x00,0x00,0xFF, 0xFF,0xFF,0xFF};
  36. ////////////////////////////////////////////////////////////////////////////////////////
  37.  
  38. int main()
  39. {
  40. HEADER.size_of_file = sizeof(HEADER) + sizeof(BGR) + sizeof(padding) * h_in_pix + 2;
  41. HEADER.reserve = 0000;
  42. HEADER.offset_of_pixle_data = 54;
  43. HEADER.size_of_header = 40;
  44. HEADER.width = w_in_pix;
  45. HEADER.hight = h_in_pix;
  46. HEADER.num_of_colour_plane = 1;
  47. HEADER.num_of_bit_per_pix = 24;
  48. HEADER.compression = 0;
  49. HEADER.size_of_pix_data = sizeof(BGR) + sizeof(padding) * h_in_pix;
  50. HEADER.h_resolution = 2835;
  51. HEADER.v_resolution = 2835;
  52. HEADER.num_of_colour_in_palette = 0;
  53. HEADER.important_colours = 0;
  54.  
  55. // write BMP Header ////////////////////////////////////////////////////////////////
  56. ofstream file;
  57. file.open ("test.bmp", ios::out | ios::trunc | ios::binary);
  58. file.write ((char*)(&BM), 2);
  59. file.write ((char*)(&HEADER), sizeof(HEADER));
  60. ////////////////////////////////////////////////////////////////////////////////////
  61. // write BMP data //////////////////////////////////////////////////////////////////
  62. //file.write ((char*)(&BGR[0]),1);
  63.  
  64.  
  65. int position = w_in_pix * h_in_pix * 3;
  66. while (position != 0)
  67. {
  68. for (int n = 0; n != w_in_pix * 3; n++)
  69. {
  70. file.write ((char*)(&BGR[position - w_in_pix * 3 + n]), 1);
  71. }
  72. file.write ((char*)(&padding), 2);
  73. position = position - w_in_pix * 3;
  74. }
  75.  
  76.  
  77. }
Reply With Quote Quick reply to this message  
Join Date: Jan 2009
Posts: 6
Reputation: BMPaul is an unknown quantity at this point 
Solved Threads: 0
BMPaul BMPaul is offline Offline
Newbie Poster

Re: Help with manually creating a BMP image

 
0
  #7
Jan 3rd, 2009
Thanks 4 all of ur help
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC