Web Analytics Made Easy -
StatCounter writing a bitmap file - CodingForum


No announcement yet.

writing a bitmap file

  • Filter
  • Time
  • Show
Clear All
new posts

  • writing a bitmap file

    hi. i tried to output a bitmap file but it seems to be invalid and hence, i can't open it.

    I've assigned values to the BITMAPINFOHEADER and colour table. Using WriteFile method, I wrote the above BITMAPINFO into a bitmap file.

    The raw pixel image is in a char array:
    unsigned char ByteImage [200*152];

    Do you know how to write the data in this ByteImage into the bitmap data part of the bitmap file?

    I tried something like:
    WriteFile(hFile, ByteImage, sizeof(ByteImage), &dwBytesWritten, NULL);

    the bitmap file is created but it can't be opened for viewing, saying that the file is not a valid bitmap format. anybody knows what went wrong?

    thanks alot

  • #2
    I don't know what you're talking about!

    You'll have to explain what language, platform, etc.. that you're working with.



    • #3
      Lanuage and platform

      I'm using C++ language and working on Windows NT platform.

      I'm trying to create a bitmap file. I've already initialised the properties needed in the BITMAPINFO structure.

      For example,
      m_DIB->bmiHeader.biWidth = 152;
      m_DIB->bmiHeader.biHeight = 200;

      Next, I need to write this BITMAPINFO structure into a .bmp file.

      WriteFile(hFile, m_DIB, sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD), &dwBytesWritten, NULL);

      Now, I need to read the bitmap data into the .bmp file.

      unsigned char ByteImage [200*152];
      dwBytesToWrite = sizeof(ByteImage);
      WriteFile(hFile, ByteImage, dwBytesToWrite, &dwBytesWritten, NULL);

      After doing this, the .bmp file is created. However, when I want to open and view it, this error message appears:
      "Paint cannot read this file. This is not a valid bitmap file, or its format is not currently supported"

      Do you have any idea what went wrong?


      • #4
        Why are you using a char array?? You should be using a BYTE array. I don't know if this will make a difference but it might.

        I think .bmp should also be written as BGR not RGB so you'll have to swap every 3rd byte with byte[n-2] ...

        It's a little hard to see the whole problem without seeing a little more code though.
        Omnis mico antequam dominus Spookster!


        • #5
          And the size of the array should be width*height*depth.
          Omnis mico antequam dominus Spookster!


          • #6
            I've managed to output a valid bitmap file now but its the image is distorted...

            What do you mean by swaping every 3rd byte with [n-2]byte?
            How do I actually go about doing that?


            • #7
              Well, you need to do a loop to swap every 3rd byte with the one 2 bytes before it. Which will convert it from RGB to BGR.

              Like --

              BYTE tmp;
              for ( int i = 3; i < array_size; i+=3 ) {
                tmp = bmp[i-2];
                bmp[i-2] = bmp[i];
                bmp[i] = tmp;
              Or you can use memmove()...

              I'm really sick right now so my thinking may be a little off, hopefully that code is actually right ..

              [edit:] Assuming I'm actually right ( are the colors wrong on the bitmap? Inverted? ) ...

              Each pixel has a color index right, each color is an RGB value.

              Bitmaps should be in the BGR format I think, at least I remember when I wrote a bitmap loader for opengl textures that it had to be transformed from BGR to RGB to use it. Which is why I believe it needs to be save in BGR...

              Anyways, the BYTE array is really just and array of colors. .. So for example -

              BYTE[0] = Red value
              BYTE[1] = Green value
              BYTE[2] = Blue value


              But, assuming my memory serves me correctly and you need to swap these bytes every set of 3 in the array would be in the format BGR

              BYTE[0] = Blue value
              BYTE[1] = Green value
              BYTE[2] = Red value

              And it just repeats like that, with BYTE[3] being blue value and BYTE[5] being red value and so on..

              I hope I haven't confused you. This better be right or I'll look like a fool..
              Last edited by Mhtml; Mar 13, 2004, 06:26 AM.
              Omnis mico antequam dominus Spookster!


              • #8
                Post your code if you still have some problems.
                Omnis mico antequam dominus Spookster!


                • #9
                  I'm trying to create a 24bit uncompressed bitmap file. the following codes gave me distorted bitmap image and appears to have 4 distinct sections.

                  // Put image data in ByteImage
                  memcpy(ByteImage,birData-> BiometricData + 24, 152*200);

                  // Bitmap file header
                  BITMAPFILEHEADER *m_header = (BITMAPFILEHEADER *) malloc(sizeof(BITMAPFILEHEADER));
                  m_header->bfType = 'MB';
                  m_header->bfSize = 0;
                  m_header->bfReserved1 = 0;
                  m_header->bfReserved2 = 0;
                  m_header->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

                  // Bitmap infoheader
                  m_DIB->biSize = sizeof (BITMAPINFOHEADER);
                  m_DIB->biWidth = 152;
                  m_DIB->biHeight = 200;
                  m_DIB->biPlanes = 1;
                  m_DIB->biBitCount = 24;
                  m_DIB->biCompression = BI_RGB; m_DIB->biSizeImage = 152*200*3;
                  m_DIB->biXPelsPerMeter = 0;
                  m_DIB->biYPelsPerMeter = 0;
                  m_DIB->biClrUsed = 0;
                  m_DIB->biClrImportant = 0;

                  unsigned char tmp;
                  for (int j = 3; j < 152*200*3; j+=3)
                  tmp = ByteImage[j-2];
                  ByteImage[j-2] = ByteImage[j];
                  ByteImage[j] = tmp;

                  // Open the file
                  wsprintf(szFileName, TEXT("c:\\Templates\\%s.bmp"), lptszUserName);
                  hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
                  if (hFile == INVALID_HANDLE_VALUE)

                  // Write BITMAPFILEHEADER
                  WriteFile(hFile, m_header, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);

                  // Write BITMAPINFOHEADER
                  WriteFile(hFile, m_DIB, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);

                  // Write bitmap data
                  WriteFile(hFile, ByteImage, sizeof(ByteImage), &dwBytesWritten, NULL);

                  // Close the file

                  I've read that behind each scan line there's some "junk bytes" appended to it. Could it be that these "junk bytes" that caused the distorted image?


                  • #10
                    junk bytes in 24-bit bitmap

                    Yes the distortion is just bcoz of junk bytes. You have to take care of junk bytes while reading or writting a 24-bit bitmap image. Since in each scan line the number of bytes should b multiple of 4, there may be some extra bytes. At the time of reading u must jump over those bytes in each scan line. And while creating a 24-bit bitmap u've to write the junk bytes into the output file.
                    To find out junk bytes in each scan line u can try the following line of code in c :--
                    int junkBytes=(fileSize - (imageSize*3 + 54)/width) / height;
                    where fileSize = total disk size of the file
                    imageSize = width * height;
                    another thing u must notice --- in ur code u've written "MB" as BMP identifier, but it should be "BM".
                    Last edited by s.basu9; Jan 2, 2007, 05:04 AM. Reason: bmp identifier