writing BITMAP header

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kr47
    New Member
    • Apr 2007
    • 1

    writing BITMAP header

    hi,
    i am attempting to split a BITMAP file into 4 parts
    in that process we have to write header for each part
    how to write the header
    please help me
    i am in deadly need
  • gpraghuram
    Recognized Expert Top Contributor
    • Mar 2007
    • 1275

    #2
    HI,
    Tell me what you have attempted on this and where r u stuck?
    Then people here can hep u...
    Thanks
    Raghuram

    Comment

    • gomanza
      New Member
      • May 2007
      • 16

      #3
      Hi Guys,

      hopefully you can help me. I have an array of number from 0-255 and I would like to create a bmp file, but only grey colors so 0 = schwarz , 255 = white.

      I am already able to write into the file with the following method: (c++)
      [PHP]
      fstream data(filename, ios::'out' | ios::binary | ios::trunc);

      if(!data.is_ope n() || data.bad())
      {
      cout << "error: cannot open file" << endl;
      exit(-1);
      }

      writeBin(data, 'B');
      writeBin(data, 'M');
      writeBin(data, (long) height*width*3+ 52);
      writeBin(data, (long) 0);
      writeBin(data, (long) 52);

      writeBin(data, (long) 40);
      writeBin(data, width);
      writeBin(data, height);
      writeBin(data, (short) 1);
      writeBin(data, (short) 8);
      writeBin(data, (long) 0);
      writeBin(data, (long) 0);
      writeBin(data, (long) 0);
      writeBin(data, (long) 0);
      writeBin(data, (long) 0);
      writeBin(data, (long) 0);

      std::vector< pix >::iterator pixIterator = grauwert.begin( );
      for (pixIterator;pi xIterator != grauwert.end(); pixIterator++)
      {
      printf("%i test",(*pixIter ator).grauwert) ;
      writeBin(data, (*pixIterator). grauwert);
      }
      data.close();
      [/PHP]

      [PHP]
      struct pix
      {
      pix():grauwert( 0 ),x(0),y(0) {}
      int grauwert;
      int x;
      int y;
      };

      //the writing method:
      template <class T>
      void writeBin(fstrea m &Out, T data)
      {
      Out.write(reint erpret_cast<cha r*> (&data), sizeof(T));
      }
      [/PHP]
      So my question is how can I edit my header, that I can use the numbers of my vector as numbers which indicate a grayvalue?

      If you have any suggestions, please feel free to answer :-)

      bye
      Last edited by gomanza; May 16 '07, 03:14 PM. Reason: a strange output from ::out that's also the reason why 'out' is marked with quotes

      Comment

      • AdrianH
        Recognized Expert Top Contributor
        • Feb 2007
        • 1251

        #4
        I'll answer this tomorrow (or maybe later tonight).


        Adrian

        Comment

        • gomanza
          New Member
          • May 2007
          • 16

          #5
          Would be cool thanks

          Originally posted by AdrianH
          I'll answer this tomorrow (or maybe later tonight).


          Adrian

          Comment

          • AdrianH
            Recognized Expert Top Contributor
            • Feb 2007
            • 1251

            #6
            Originally posted by gomanza
            Would be cool thanks
            Oops, sorry. I forgot. :o :blush: So here is my response.

            In the method you are describing, you have a bunch of pix objects. Can they can be in any order? If so, you will have to generate the image array prior to writing it to disk or you will have to seek around the file as you write the pixels in.

            On a stylistic (and perhaps personal) note, I would recommend using BITMAPINFO and BITMAPFILEHEADE R structures, filling them in and writing these structures out to disk. This can make it easier to read and understand your code. For more information on these you can look here. The following is your code with the names of the fields put in as comments to the right:
            [code=cpp]writeBin(data, 'B'); // bfType
            writeBin(data, 'M');
            writeBin(data, (long) height*width*3+ 52); // bfSize
            writeBin(data, (long) 0); // bfReserved0
            writeBin(data, (long) 52); // bfReserved1
            // bfOffBits

            writeBin(data, (long) 40); // blSize
            writeBin(data, width); // biWidth
            writeBin(data, height); // biHight
            writeBin(data, (short) 1); // biPlains
            writeBin(data, (short) 8); // biBitCount
            writeBin(data, (long) 0); // biCompression
            writeBin(data, (long) 0); // biSizeImage
            writeBin(data, (long) 0); // biXPelsPerMeter
            writeBin(data, (long) 0); // biYPelsPerMeter
            writeBin(data, (long) 0); // biClrUsed
            writeBin(data, (long) 0); // biClrImportant
            [/code]

            There are a few errors here. You are not supposed to fill in reserved areas. You image size is not defined. I would not use (long)40 for blSize but instead use sizeof(BITMAPIN FOHEADER). You haven’t specified bfOffBits. The list goes on.

            Follow the link I provided for more information.


            Adrian

            Comment

            • gomanza
              New Member
              • May 2007
              • 16

              #7
              Hi thanks,

              I resolved almost all everything, but I still have a header error (I guess). Windows says not defined bmp.

              so here is my header
              [PHP]
              ofstream os(filename.c_s tr(), ios::out | ios::trunc | ios::binary);
              if (!os.is_open()) return false;

              BITMAPINFOHEADE R bmpinfo;
              bmpinfo.biSize = 40;
              bmpinfo.biWidth = width;
              bmpinfo.biHeigh t = height;
              bmpinfo.biPlane s = 1;
              bmpinfo.biBitCo unt = 24;
              bmpinfo.biCompr ession = 0;
              bmpinfo.biSizeI mage = width * height * 3;
              bmpinfo.biXPels PerMeter = 0;
              bmpinfo.biYPels PerMeter = 0;
              bmpinfo.biClrUs ed = 0;
              bmpinfo.biClrIm portant = 0;

              BITMAPFILEHEADE R bmpfile;
              bmpfile.bfType = 0x4D42;
              bmpfile.bfSize = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER) + (sizeof(RGB) * (width*height)) ;
              bmpfile.bfReser ved1 = 0;
              bmpfile.bfReser ved2 = 0;
              bmpfile.bfOffBi ts = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER);

              os.write((char* )&bmpfile, sizeof(bmpfile) );
              os.write((char* )&bmpinfo, sizeof(bmpinfo) );
              [/PHP]

              !!Just a tipp!! for newbies like me :-): For saving a grayscale bmp file set RGB on the same values. For example: grayscalenumber = 55 so R = 55 G = 55 B = 55

              If somebody see's an error in my header please let me know

              thanks so far Gomanza

              Comment

              • gomanza
                New Member
                • May 2007
                • 16

                #8
                And another thing

                Check this out:

                http://www.wotsit.org/list.asp?al=B

                Comment

                • AdrianH
                  Recognized Expert Top Contributor
                  • Feb 2007
                  • 1251

                  #9
                  Originally posted by gomanza
                  Hi thanks,

                  I resolved almost all everything, but I still have a header error (I guess). Windows says not defined bmp.

                  so here is my header
                  [code=cpp]
                  ofstream os(filename.c_s tr(), ios::out | ios::trunc | ios::binary);
                  if (!os.is_open()) return false;

                  BITMAPINFOHEADE R bmpinfo;
                  bmpinfo.biSize = 40;
                  bmpinfo.biWidth = width;
                  bmpinfo.biHeigh t = height;
                  bmpinfo.biPlane s = 1;
                  bmpinfo.biBitCo unt = 24;
                  bmpinfo.biCompr ession = 0;
                  bmpinfo.biSizeI mage = width * height * 3;
                  bmpinfo.biXPels PerMeter = 0;
                  bmpinfo.biYPels PerMeter = 0;
                  bmpinfo.biClrUs ed = 0;
                  bmpinfo.biClrIm portant = 0;

                  BITMAPFILEHEADE R bmpfile;
                  bmpfile.bfType = 0x4D42;
                  bmpfile.bfSize = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER) + (sizeof(RGB) * (width*height)) ;
                  bmpfile.bfReser ved1 = 0;
                  bmpfile.bfReser ved2 = 0;
                  bmpfile.bfOffBi ts = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER);

                  os.write((char* )&bmpfile, sizeof(bmpfile) );
                  os.write((char* )&bmpinfo, sizeof(bmpinfo) );
                  [/code]

                  !!Just a tipp!! for newbies like me :-): For saving a grayscale bmp file set RGB on the same values. For example: grayscalenumber = 55 so R = 55 G = 55 B = 55

                  If somebody see's an error in my header please let me know

                  thanks so far Gomanza
                  Sorry that I haven't responded to this earlier. Having problems loosing threads every so often. Please bump the thead by posting something to it if you don't get a responce after a while.

                  You don't have to set the grayscale value using R = 55, G=55 and B=55, just declare the bitmap as a 8 bit instead of a 24 bit bitmap. Of course, I've not used this in a while so I could be wrong. ;)

                  Also, include the Windows.h header file to fix the error you are referring to (unless I have misinterpreted, if so, post the message as it is outputted by the compiler).


                  Adrian

                  Comment

                  • gomanza
                    New Member
                    • May 2007
                    • 16

                    #10
                    8bit didn't work very well anyway 24bit and RGB = same number works somehow. :-)

                    So here is my Class
                    [PHP]

                    //Grafikfunctions .h:
                    #pragma once

                    #include <windows.h>
                    #include <string>
                    #include <vector>
                    #include <fstream>
                    #include <iostream>
                    #include <fstream>
                    #include <cstdlib>
                    #include <string>
                    #include <ctime>

                    using namespace std;

                    struct RGB
                    {
                    BYTE blue;
                    BYTE green;
                    BYTE red;
                    };


                    class Graficfunctions
                    {
                    private:
                    long width;
                    long height;
                    vector<RGB> colors;
                    vector<RGB> tempColor;

                    public:
                    Graficfunctions ();
                    ~Graficfunction s();

                    void arrayReorder();
                    void setPixelColor(l ong x, long y, BYTE red, BYTE green, BYTE blue);
                    void setPixelColor(l ong x, long y, RGB newColor);
                    void setWidth(long nwidth);
                    void setHeight(long nheight);

                    bool to8Bmp(std::str ing filename,int height, int width);

                    };

                    //Grafikfunctions .cpp:
                    #include "Graficfunction s.h"

                    using namespace std;

                    Graficfunctions ::Graficfunctio ns() {
                    }

                    Graficfunctions ::~Graficfuncti ons() {

                    }

                    void Graficfunctions ::setPixelColor (long x, long y, BYTE red, BYTE green, BYTE blue)
                    {
                    RGB newCol;
                    newCol.red = red;
                    newCol.green = green;
                    newCol.blue = blue;
                    colors.push_bac k(newCol);
                    }

                    void Graficfunctions ::setPixelColor (long x, long y, RGB newColor)
                    {
                    colors.push_bac k(newColor);
                    }

                    void Graficfunctions ::arrayReorder( ) {

                    }

                    void Graficfunctions ::setWidth(long nwidth) {
                    width = nwidth;
                    }

                    void Graficfunctions ::setHeight(lon g nheight){
                    height = nheight;
                    }

                    bool Graficfunctions ::to8Bmp(string filename,int height,int width)
                    {
                    //unsigned register long i;
                    ofstream os(filename.c_s tr(), ios::out | ios::trunc | ios::binary);
                    if (!os.is_open()) return false;

                    BITMAPINFOHEADE R bmpinfo;
                    bmpinfo.biSize = 40;
                    bmpinfo.biWidth = width;
                    bmpinfo.biHeigh t = height;
                    bmpinfo.biPlane s = 1;
                    bmpinfo.biBitCo unt = 24;
                    bmpinfo.biCompr ession = 0;
                    bmpinfo.biSizeI mage = width * height * 3+52;
                    bmpinfo.biXPels PerMeter = 0;
                    bmpinfo.biYPels PerMeter = 0;
                    bmpinfo.biClrUs ed = 0;
                    bmpinfo.biClrIm portant = 0;

                    BITMAPFILEHEADE R bmpfile;
                    bmpfile.bfType = 0x4D42;
                    bmpfile.bfSize = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER) + (sizeof(RGB) * (width*height)) ;
                    bmpfile.bfReser ved1 = 0;
                    bmpfile.bfReser ved2 = 0;
                    bmpfile.bfOffBi ts = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER);

                    os.write((char* )&bmpfile, sizeof(bmpfile) );
                    os.write((char* )&bmpinfo, sizeof(bmpinfo) );

                    //Bilddaten einfügen:
                    int i=0;
                    vector<RGB>::it erator myiteratorColor ;
                    for(myiteratorC olor = colors.begin(); myiteratorColor != colors.end(); myiteratorColor ++){
                    os.write((char* )&(*(myiterator Color)), sizeof(RGB));
                    i++;
                    }

                    os.close();
                    printf("File created\n");
                    return true;
                    }

                    [/PHP]

                    The compiler does not bring any error it works until I try to open a file with the Windows picture viewer. Can I send you such a image file?

                    Sorry have to leave work now I'll be back tomorrow

                    Comment

                    • AdrianH
                      Recognized Expert Top Contributor
                      • Feb 2007
                      • 1251

                      #11
                      Originally posted by gomanza
                      8bit didn't work very well anyway 24bit and RGB = same number works somehow. :-)
                      Hmmm, dunno. I've just dumpped entire 256 grey scale images before, but its been a while (few years). If you don't mind using 24bit colour, then I'll leave it at that. ;)

                      Originally posted by gomanza
                      The compiler does not bring any error it works until I try to open a file with the Windows picture viewer. Can I send you such a image file?
                      Sure, umm, not sure. I am not aware of any method for you to send it to me. I don't post my email due to spam reasons. Maybe you can find a place to host the file for a short time?

                      Originally posted by gomanza
                      Sorry have to leave work now I'll be back tomorrow
                      No prob. Its late anyway. ;)


                      Adrian

                      Comment

                      • gomanza
                        New Member
                        • May 2007
                        • 16

                        #12
                        Hi Adrian,

                        ok here you can download 2 of my files.
                        The interesting file is Graficfunctions .cpp



                        I guess 24bit are ok. You can also find a 24bit bmp and a picture that shows what my programm produces if the header is on 8bit.

                        gomanza

                        Comment

                        • gomanza
                          New Member
                          • May 2007
                          • 16

                          #13
                          I just found another possibility do you know how this works?

                          http://msdn2.microsoft .com/en-us/library/ms532305.aspx

                          Comment

                          • gomanza
                            New Member
                            • May 2007
                            • 16

                            #14
                            Sorry couldn't edit my message:

                            I just found another possibility do you know how this works?

                            http://msdn2.microsoft .com/en-us/library/ms532305.aspx

                            edit: ok its not that difficult, haven't tried it yet cause of time.

                            Another interesting thing about my putput pictures: I cannot load them with openCV. I guess it is the same problem as windows has.

                            I also player a little with my header configuration:
                            [PHP]
                            BITMAPINFOHEADE R bmpinfo;
                            bmpinfo.biSize = sizeof(BITMAPIN FOHEADER);
                            bmpinfo.biWidth = width;
                            bmpinfo.biHeigh t = -height; //minus just to mirror the picture
                            bmpinfo.biPlane s = 1;
                            bmpinfo.biBitCo unt = 24;
                            bmpinfo.biCompr ession = BI_RGB; //BI_RGB is 0
                            bmpinfo.biSizeI mage = ((((width * bmpinfo.biBitCo unt) + 31) & ~31) >> 3) * height; //width * height * 3; //width = 64 height = 48
                            bmpinfo.biXPels PerMeter = 0;
                            bmpinfo.biYPels PerMeter = 0;
                            bmpinfo.biClrUs ed = 0;
                            bmpinfo.biClrIm portant = 0;

                            BITMAPFILEHEADE R bmpfile;
                            bmpfile.bfType = 0x4D42;
                            bmpfile.bfSize = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER) + (sizeof(RGB) * (width*height)) ;
                            bmpfile.bfReser ved1 = 0;
                            bmpfile.bfReser ved2 = 0;
                            bmpfile.bfOffBi ts = sizeof(BITMAPFI LEHEADER) + sizeof(BITMAPIN FOHEADER);

                            [/PHP]

                            Comment

                            • gomanza
                              New Member
                              • May 2007
                              • 16

                              #15
                              problem half solved:

                              preknowledge: grayscale picture R & G & B same number!!

                              Yippi I just figured out by comparing the hex files of a incorrupt and a corrupt bmp file that there is a 00 after every RGB numbers:

                              [PHP]
                              // incorrupt file
                              4b 4b 4b 00 ff ff ff 00 ....
                              //corrupt file
                              4b 4b 4b ff ff ff
                              [/PHP]
                              -> I miss something in between :-)

                              so I just added another BYTE to my struct RGB. By definition this byte is 0
                              [PHP]
                              struct RGB
                              {
                              BYTE blue;
                              BYTE green;
                              BYTE red;
                              BYTE zero;
                              };
                              [/PHP]

                              The result is no longer a grayscale picture:


                              let's see what I can figure out

                              gomanza

                              Comment

                              Working...