C++ 从数字数组创建8位位图

C++ 从数字数组创建8位位图,c++,bitmap,mfc,C++,Bitmap,Mfc,这困扰了我一段时间,我想确保我对位图的理解是正确的,并得到一些帮助来发现错误。基本上,我要做的是保存一个8位位图文件,同时在MFC应用程序的图片框中显示它。我想避免保存位图然后再次加载的麻烦方法 保存文件的操作基本上是成功的,但是我修改了我的代码,现在文件中以前是白色的(在这个例子中是黑白图像)通常显示为绿色,但它会改变。我猜这是因为我的数据引用了颜色表中的信息,哪个值可能是白色的 HBITMAP ReadWrite::SaveFile(LPCTSTR file, double* data) {

这困扰了我一段时间,我想确保我对位图的理解是正确的,并得到一些帮助来发现错误。基本上,我要做的是保存一个8位位图文件,同时在MFC应用程序的图片框中显示它。我想避免保存位图然后再次加载的麻烦方法

保存文件的操作基本上是成功的,但是我修改了我的代码,现在文件中以前是白色的(在这个例子中是黑白图像)通常显示为绿色,但它会改变。我猜这是因为我的数据引用了颜色表中的信息,哪个值可能是白色的

HBITMAP ReadWrite::SaveFile(LPCTSTR file, double* data) {

    BYTE* bmp = ConvertData(data);
    HANDLE hf;
    BITMAPINFO* pbmi = WriteHeader(file);

    BITMAPFILEHEADER* bmfh = (BITMAPFILEHEADER*)alloca(sizeof(BITMAPFILEHEADER));
    bmfh->bfType = 0x4d42; // 'BM'
    bmfh->bfReserved1 = 0;
    bmfh->bfReserved2 = 0;
    bmfh->bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbmi->bmiHeader.biSize + 256 * sizeof(RGBQUAD);
    bmfh->bfSize = (DWORD)(bmfh->bfOffBits + pbmi->bmiHeader.biSizeImage);


    hf = CreateFile(file, GENERIC_READ | GENERIC_WRITE, (DWORD) 0,
        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL );

    if (hf == NULL) // error creating
    {
        CloseHandle (hf);
        return NULL;
    }

    // write header
    unsigned long bwritten;
    if (!WriteFile(hf, (LPCVOID)bmfh, sizeof(BITMAPFILEHEADER), &bwritten, NULL))
    {
        CloseHandle (hf);
        return NULL;
    }

    // write infoheader
    if (!WriteFile(hf, (LPCVOID)pbmi, sizeof (BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), &bwritten, NULL ))
    {   
        CloseHandle (hf);
        return NULL;
    }

    // write image data
    if (!WriteFile(hf, (LPCVOID)bmp_data, (int) pbmi->bmiHeader.biSizeImage, &bwritten, NULL ))
    {   
        CloseHandle (hf);
        return NULL;
    }

    // Close
    CloseHandle(hf);

    // Send back a file to display
    return CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void**)bmp_data, NULL, 0);
}
编写infoheader+调色板的代码(应该是从黑色到白色的值??)

BITMAPINFO*ReadWrite::WriteHeader(LPCTSTR fn)
{
int R=ReadWrite::getR();
int C=ReadWrite::getC();
BITMAPINFO*pbmi=(BITMAPINFO*)alloca(sizeof(BITMAPINFO标头)+sizeof(RGBQUAD)*256);
pbmi->bmiHeader.biSize=sizeof(BitMapInfo头文件);
pbmi->bmiHeader.biWidth=R;
pbmi->bmiHeader.biHeight=-C;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biBitCount=8;
pbmi->bmiHeader.biCompression=BI_RGB;
pbmi->bmiHeader.biizeImage=((R*pbmi->bmiHeader.bibibitCount+31)和~31)>>3)*C;
pbmi->bmiHeader.biclrued=256;
pbmi->bmiHeader.biClrImportant=0;
对于(int i=0;ibmiColors[i].rgbreed=i;
pbmi->bmiColors[i].rgbGreen=i;
pbmi->bmiColors[i].rgbBlue=i;
pbmi->bmiColors[i].rgbReserved=0;
}
//返回true;
返回pbmi;
}
最后将我的数字数组转换为无符号字符“字节”:

BYTE* ReadWrite::ConvertData(double* data) {

    BYTE* bmp_data;
    int R = ReadWrite::getR();
    int C = ReadWrite::getC();
    bool binary = ReadWrite::getBinary();

    bmp_data = new BYTE [R*C];

    // convert the values to unsigned char (BYTE)
    for(int i=0; i<R*C; i++){
        if (data[i] == 1){
            data[i] = 255;
        }
        bmp_data[i] = (unsigned char)data[i];
    }

    delete [] data;

    return bmp_data;
}
BYTE*ReadWrite::ConvertData(双*数据){
字节*bmp_数据;
int R=ReadWrite::getR();
int C=ReadWrite::getC();
bool binary=ReadWrite::getBinary();
bmp_data=新字节[R*C];
//将值转换为无符号字符(字节)

对于(int i=0;i,因此我发现我的代码存在问题,导致其他应用程序/互联网出现错误

在其中,为了翻转数据,我给图像的高度指定了一个负值,但这是一个完全不正确的解决方案。取而代之的是:

// convert the integer values to unsigned char (BYTE) BACKWARDS
for(int i=0; i<R; i++){
    for(int j=0; j<C; j++){
        if (data[i*R + j] == 1 && binary){
            data[i*R + j] = 255;
        }
        bmp_data[(R-i)*C + (j-C)] = (unsigned char)data[i*C + j];
    }
}
//将整数值向后转换为无符号字符(字节)

对于(int i=0;我看不到从何处释放此行分配的缓冲区:
BITMAPINFO*pbmi=(BITMAPINFO*)alloca…
。此外,从何处删除此缓冲区:
bmp\u data=new BYTE[R*C]
它们用于CreateDIBSection,如果我在返回之前删除它们,我会得到错误。我是否正确地认为,一旦HBITMAP对象被删除(在某个点上),那么它们也就不存在了?我确实删除了
bmfh
,因为在它写入文件之后就不需要这样做了?
// convert the integer values to unsigned char (BYTE) BACKWARDS
for(int i=0; i<R; i++){
    for(int j=0; j<C; j++){
        if (data[i*R + j] == 1 && binary){
            data[i*R + j] = 255;
        }
        bmp_data[(R-i)*C + (j-C)] = (unsigned char)data[i*C + j];
    }
}