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