user3214228
user3214228

Reputation: 19

Read and convert Monochrome bitmap file into CByteArray MFC

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.

Upvotes: 1

Views: 1799

Answers (1)

Roger Rowland
Roger Rowland

Reputation: 26279

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.

Upvotes: 1

Related Questions