BOOL SaveBmp(HBITMAP hBitmap, CString FileName) { HDC hDC; //当前分辨率下每象素所占字节数 int iBits; //位图中每象素所占字节数 WORD wBitCount; //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数 DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; //位图属性结构 BITMAP Bitmap; //位图文件头结构 BITMAPFILEHEADER bmfHdr; //位图信息头结构 BITMAPINFOHEADER bi; //指向位图信息头结构 LPBITMAPINFOHEADER lpbi; //定义文件,分配内存句柄,调色板句柄 HANDLE fh, hDib, hPal,hOldPal=NULL; //计算位图文件每个像素所占字节数 hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); DeleteDC(hDC); if (iBits <= 1) wBitCount = 1; else if (iBits <= 4) wBitCount = 4; else if (iBits <= 8) wBitCount = 8; else wBitCount = 24; GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);//a handle,the number of imformation,the pointer to a buffer bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrImportant = 0; bi.biClrUsed = 0; dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight; //为位图内容分配内存 hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; ////////////////////////////////////////////这里错了//////////////// // 处理调色板 hPal = GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = ::GetDC(NULL); hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE); RealizePalette(hDC); } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); //恢复调色板 if (hOldPal) { ::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE); RealizePalette(hDC); ::ReleaseDC(NULL, hDC); } //创建位图文件 fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (fh == INVALID_HANDLE_VALUE) return FALSE; // 设置位图文件头 bmfHdr.bfType = 0x4D42; // "BM" dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; // 写入位图文件头 WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图文件其余内容 WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); //清除 GlobalUnlock(hDib); GlobalFree(hDib); CloseHandle(fh); return TRUE; } ////////////////////////////////////////////////////////////////////////////截图 |
|
20分 |
lpbi内存分陪成功了吗, 如果成功了两个结构体赋值还是有问题,那么就把结构体内的元素一个一个的赋值看看
BITMAPINFOHEADER |
20分 | |
20分 |
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
|
20分 | |
检查一下GetObject有没有成功,
|
|
检查一下 dwBmBitsSize 这个值 是多少就知道了。
|
|
20分 |
加入检测语句检测GlobalAlloc和Globallock两个函数的返回值,可调用GetLastError以获得更多错误信息,有可能是分配失败或者传入GlobalAlloc的分配的字节数的参数为0导致的
|
问题检测出来是调用函数时的出问题。debug了半天,不出bug了,但和期望不一样,bitmap显示为全黑,现在把源码贴出来。。。
———————— int _tmain(int argc, _TCHAR* argv[]) { //Initiation&Declear _TCHAR* filename=_T("regenerate_original_picture.txt"); HDC hDC; unsigned short *data =(unsigned short*)malloc(256); static unsigned short *ImageData[256][256][128]; BOOL SaveBmp(HBITMAP hBitmap, CString FileName); HBITMAP hBitmap; BITMAPINFO *bmi=(BITMAPINFO*)malloc(sizeof(BITMAPINFO)) ; unsigned short * pBits =(unsigned short*)malloc(256*256*2); memset( pBits, 0xf9, 256*256*2 );//pBits是内容// 一旦create了,就可以直接操控PB IT s这个指针,//*( PB IT s + xxxx ) = 255; // 对某个像素赋值. //填装数据 //FILE *pfile=_tfopen(filename,_T("rb"));//rb要用_T转换一下 //for (int i = 0; i < 256; i++) // for (int j = 0; j < 256; j++) //{ // fread(data, 2, 128, pfile); // //dosomething //pBits,data,memcpy; // for (int k = 0; k < 128; k++) // { // ImageData[i][j][k]=data; // data++; // } // data =(data-128); //} // int x=1;//x是标示波段的 // for (int v = 0; v < 256; v++) // for (int c = 0; c < 256; c++) // { // memcpy( pBits,ImageData[v][c][x],1); // pBits++; // } //CreateDIBitmap创建的是设备相关位图句柄 - HBITMAP. //CreateDIBSection创建的是设备无关位图句柄 - HBITMAP. //初始化BITMAPINFOHEADER结构的栏位 bmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER) ; bmi->bmiHeader.biWidth = 256 ; bmi->bmiHeader.biHeight = 256 ; bmi->bmiHeader.biPlanes = 1 ; bmi->bmiHeader.biBitCount = 16 ; bmi->bmiHeader.biCompression = BI_RGB ; bmi->bmiHeader.biSizeImage = 256*256*16 ; bmi->bmiHeader.biXPelsPerMeter = 0 ; bmi->bmiHeader.biYPelsPerMeter = 0 ; bmi->bmiHeader.biClrUsed = 0 ; bmi->bmiHeader.biClrImportant = 0 ; printf("%d\n",GetLastError()); //在基本准备後,我们呼叫该函式: hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL); hBitmap = CreateDIBSection (hDC, (BITMAPINFO *) bmi,DIB_RGB_COLORS, (void**)&pBits, NULL, 0) ; //HDC hd; //hBitmap = CreateDIBSection (hd, (BITMAPINFO *) bmi,DIB_RGB_COLORS, (void**)&pBits, NULL, 0) ; printf("%d\n",GetLastError()); SaveBmp(hBitmap,"bitmap"); return 0; } ———————–问题1 |
|
眼拙,没有看到哪句为bi分配内存。
|
|
GlobalAlloc的第一个参数可以改为GPTR,结构体应该不能直接=吧
|