1

In my MFC project, I need to read and convert a Monochrome bitmap file into CByteArray. While reading the bitmap file by using 'CFile' class with the mode of 'Read', it seems like it gives more length than its original.

My MFC code:-

CFile ImgFile;
CFileException FileExcep;
CByteArray* pBinaryImage = NULL;
strFilePath.Format("%s", "D:\\Test\\Graphics0.bmp");

if(!ImgFile.Open((LPCTSTR)strFilePath,CFile::modeReadWrite,&FileExcep))
{
    return NULL;
}   
pBinaryImage = new CByteArray();
pBinaryImage->SetSize(ImgFile.GetLength());

// get the byte array's underlying buffer pointer
LPVOID lpvDest = pBinaryImage->GetData();

// perform a massive copy from the file to byte array
if(lpvDest)
{
    ImgFile.Read(lpvDest,pBinaryImage->GetSize());
}
    ImgFile.Close();

Note: File length is been set to bytearray obj.

I checked with C# with the following sample:-

        Bitmap bmpImage = (Bitmap)Bitmap.FromFile("D:\\Test\\Graphics0.bmp");
        ImageConverter ic = new ImageConverter();
        byte[] ImgByteArray = (byte[])ic.ConvertTo(bmpImage, typeof(byte[]));

While comparing the size of "pBinaryImage" and "ImgByteArray", its not same and I guess "ImgByteArray" size is the correct one since from this array value, I can get my original bitmap back.

  • Your C# example parses the bitmap header and only gives you the pixels. Your MFC example reads the whole bitmap, headers included, and you have no idea where the pixel data is. You need to be aware of the bitmap file format before reading. – Roger Rowland Jan 20 '14 at 08:31
  • @RogerRowland : Thanks for your comment. I have checked both bytearray sizes with my other bitmaps. Most of the time, both are same. For few bitmaps, they are not. Then only I doubted with the size to be read. It would be helpful for me, if you give the solution. – user3214228 Jan 20 '14 at 09:18

1 Answers1

1

As I noted in comments, by reading the whole file with CFile, you are also reading the bitmap headers, which will be corrupting your data.

Here is an example function, showing how to load a monochrome bitmap from file, wrap it in MFC's CBitmap object, query the dimensions etc. and read the pixel data into an array:

void LoadMonoBmp(LPCTSTR szFilename)
{
    // load bitmap from file
    HBITMAP hBmp = (HBITMAP)LoadImage(NULL, szFilename, IMAGE_BITMAP, 0, 0,
                                          LR_LOADFROMFILE | LR_MONOCHROME);

    // wrap in a CBitmap for convenience
    CBitmap *pBmp = CBitmap::FromHandle(hBmp);

    // get dimensions etc.
    BITMAP pBitMap;
    pBmp->GetBitmap(&pBitMap);

    // allocate a buffer for the pixel data
    unsigned int uBufferSize = pBitMap.bmWidthBytes * pBitMap.bmHeight;
    unsigned char *pPixels = new unsigned char[uBufferSize];

    // load the pixel data
    pBmp->GetBitmapBits(uBufferSize, pPixels);

    // ... do something with the data ....

    // release pixel data
    delete [] pPixels;
    pPixels = NULL;

    // free the bmp
    DeleteObject(hBmp);
}

The BITMAP structure will give you information about the bitmap (MSDN here) and, for a monochrome bitmap, the bits will be packed into the bytes you read. This may be another difference with the C# code, where it is possible that each bit is unpacked into a whole byte. In the MFC version, you will need to interpret this data correctly.

Roger Rowland
  • 25,885
  • 11
  • 72
  • 113