创建位图的函数,没有成功,请高手帮忙看看,分析哪里错了。非常感谢!
其中cx,cy为位图高度,ibitcount为位深度,lpData为图像数据,bSave为是否保存标志。HBITMAP CreatBMP(long cx, long cy, UINT ibitcount, LPBYTE lpData, bool bSave)
{
//  宽度为 4 的整数倍
cx = ((cx+3)/4 * 4);   ASSERT((ibitcount == 1) || (ibitcount == 4) ||
(ibitcount == 8) || (ibitcount == 16) 
|| (ibitcount == 24) ||(ibitcount == 32));

    int iSize = sizeof(BITMAPINFOHEADER);
switch(ibitcount){
case 8:
iSize += 4*4;
break;
case 1:
case 4:
case 16:
case 24:
case 32:
break;
default:
break;
} //  创建信息头
BITMAPINFO* pBmpInfo;
BYTE *pByte;
pByte = new BYTE[iSize];
pBmpInfo = (BITMAPINFO*) pByte;
    memset(pBmpInfo, 0, iSize); pBmpInfo->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
pBmpInfo->bmiHeader.biWidth       = cx;
pBmpInfo->bmiHeader.biHeight      = cy;
pBmpInfo->bmiHeader.biPlanes      = 1;
pBmpInfo->bmiHeader.biBitCount    = ibitcount;
pBmpInfo->bmiHeader.biCompression = BI_RGB;
pBmpInfo->bmiHeader.biSizeImage   = 0;
pBmpInfo->bmiHeader.biClrUsed     = 0; //  创建DIB
CDC *pDC = new CDC;
pDC->CreateCompatibleDC(NULL);
LPVOID lpBits;
HBITMAP hDIB = ::CreateDIBSection(pDC->GetSafeHdc(),
pBmpInfo,
DIB_RGB_COLORS,
                            &lpBits,
                            NULL,
                            0);

//  填充图像数据
LONG lineBytes = cx * ibitcount*8;
memcpy(lpBits, (void* )lpData, lineBytes*cy);

//  是否保存
if( bSave )
{
int iBmpBytes = cx * cy * ibitcount/8;
BITMAPFILEHEADER fileHeader;
ZeroMemory(&fileHeader, sizeof(BITMAPFILEHEADER));
*((char* )&fileHeader.bfType)      = 'B';
        *(((char*)&fileHeader.bfType) + 1) = 'M';
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) +
                     sizeof(BITMAPINFOHEADER) + ibitcount*sizeof(RGBTRIPLE);
fileHeader.bfSize      = fileHeader.bfOffBits + iBmpBytes; CFile file;
if(file.Open("temp.bmp", CFile::modeWrite | CFile::modeCreate))
{
file.Write(&fileHeader, sizeof(BITMAPFILEHEADER));
file.Write(&(pBmpInfo->bmiHeader), sizeof(BITMAPINFOHEADER));
file.WriteHuge(lpBits, iBmpBytes);
file.Close();
}
} delete pDC;
delete pBmpInfo;
delete pByte; return hDIB;
}一执行就s了啊。

解决方案 »

  1.   

    参考:
    http://community.csdn.net/Expert/topic/3567/3567472.xml?temp=.551449
      

  2.   

    先用MessageBox调试看是什么地方的问题
      

  3.   

    bitcount = 4时iSize = 16
    bitcount = 8时isize = 256*4 = 1024
    计算行像数个数,4字节对齐
    这两句都有问题
    LONG lineBytes = cx * ibitcount*8;  这里应该是(cx*ibitcount/8 +3)/4*4
    memcpy(lpBits, (void* )lpData, lineBytes*cy);另的地方不看了
      

  4.   

    多谢各位引导,图像保存部分已经参考SaveDIB()解决(是《VC数字图像处理》里的吧?
    )。To  MZP(mzp): 首先谢了。还有,bitcount=4 时iSize += 16*4 吧?这一句
    memcpy(lpBits, (void* )lpData, lineBytes*cy);哪里错了?麻烦大家帮帮忙,主要是创建部分。
      

  5.   

    后边一句没有问题,呵呵!
    bitcount=4 时iSize += 16*4 是对的。
      

  6.   

    pBmpInfo->bmiHeader.biSizeImage   = 0;?????????另:对于16色/256位图,还需要自己创建调色板。
      

  7.   

    TO DentistryDoctor: 
        biSizeImage = 0 没错的,当不使用压缩时置0。
        调色板可能要考虑。但是我创建24位色位图时程序也不行。不知道是不是创建过程逻辑有问题。热切期望各位再帮忙!多谢。
      

  8.   

    void CCreateRandomBMPDlg::OnBtnCreateBMP()
    {
    CDC dc;
    dc.CreateDC("DISPLAY", NULL, NULL, NULL);
    CBitmap bm;
    int Width = 800;//GetSystemMetrics(SM_CXSCREEN);
    int Height = 600;//GetSystemMetrics(SM_CYSCREEN);
    bm.CreateCompatibleBitmap(&dc, Width, Height);
    CDC tdc;
    tdc.CreateCompatibleDC(&dc);
    CBitmap* pOld = tdc.SelectObject(&bm);
    tdc.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
    tdc.SelectObject(pOld); BITMAP btm;
    bm.GetBitmap(&btm);
    DWORD size = btm.bmWidthBytes* btm.bmHeight;
    LPSTR lpData = (LPSTR) GlobalAllocPtr(GPTR, size);
    /////////////////////////////////////////////
    /////////////////////////////////////////////
    BITMAPINFOHEADER bih;
    bih.biBitCount = btm.bmBitsPixel;
    bih.biClrImportant = 0;
    bih.biClrUsed = 0;
    bih.biCompression = 0;
    bih.biHeight = btm.bmHeight;
    bih.biPlanes = 1;
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biSizeImage = size;
    bih.biWidth = btm.bmWidth;
    bih.biXPelsPerMeter = 0;
    bih.biYPelsPerMeter = 0;
    ///////////////////////////////////
    GetDIBits(dc, bm, 0, bih.biHeight, lpData, (BITMAPINFO *) &bih,
    DIB_RGB_COLORS);
    // bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱
    //////////////////////////////
    //修改RGB值
    int nWidth = btm.bmWidth * 4;
    for (int i = 0; i < btm.bmHeight; i++)
    {
    for (int j = 0; j < btm.bmWidth; j++)
    {
    lpData[i * nWidth + j * 4 + 2] = GetRandomRGBValue(); //R
    lpData[i * nWidth + j * 4 + 1] = GetRandomRGBValue(); //G
    lpData[i * nWidth + j * 4] = GetRandomRGBValue(); //B
    TRACE("\nR = %d; G = %d; B = %d\n",
    lpData[i * nWidth + j * 4 + 2],
    lpData[i * nWidth + j * 4 + 1], lpData[i * nWidth + j * 4]);
    }
    } static int filecount = 0;
    CString name;
    name = "D:\\Test.bmp";//m_Path+name;
    BITMAPFILEHEADER bfh;
    bfh.bfReserved1 = bfh.bfReserved2 = 0;
    bfh.bfType = ((WORD) ('M' << 8) | 'B');
    bfh.bfSize = 54 + size;
    bfh.bfOffBits = 54; CFile bf;
    if (bf.Open(name, CFile::modeCreate | CFile::modeWrite))
    {
    bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
    bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
    bf.WriteHuge(lpData, size);
    bf.Close();
    }
    GlobalFreePtr(lpData);
    AfxMessageBox("Create BMP File Over!");
    }
      

  9.   

    TO Wyhshp(阿呆) :我现在主要是想创建DIB,并得到该hDIB, 函数CreateDIBSection会处理相关部分的。TO vcleaner:创建的时候只要得到句柄就行,如果我要保存或显示,需要的时候再利用hDIB处理。