先用loadimage打开个bmp图然后放入dc后修改了些再怎么把dc 转 hbitmap 保存成bmp图?求详解

解决方案 »

  1.   

    这儿有个代码:
    WORD wbitsCount;//位图中每个像素所占字节数。
           DWORD dwpalettelsize=0;//调色板大小
           DWORD dwbmdibitsize,dwdibsize,dwwritten;
           BITMAP bitmap;//定义了位图的各种的信息。
           BITMAPFILEHEADER bmfhdr;//定义了大小、类型等BMP文件的信息。
           BITMAPINFOHEADER bi;
           LPBITMAPINFOHEADER lpbi;
           HANDLE fh,fdib;
    GetObject(hBitmap,sizeof(BITMAP),(void *)&bitmap);//得到BITMAP结构。
           //以下代码是用BITMAP的信息填充BITMAPINFOHEADER结构
           wbitsCount=bitmap.bmBitsPixel;
    bi.biSize=sizeof(BITMAPINFOHEADER);
           bi.biWidth=bitmap.bmWidth;
           bi.biHeight=bitmap.bmHeight;
           bi.biPlanes=1;
           bi.biBitCount= bitmap.bmBitsPixel ;
           bi.biClrImportant=0;
           bi.biClrUsed=0;
           bi.biCompression=BI_RGB;
           bi.biSizeImage=0;
           bi.biYPelsPerMeter=0;
           bi.biXPelsPerMeter=0;
    //以下代码是获取调色板的长度,调色板现在的用处很少,因为256色的位图已经不多了。
           if(wbitsCount<=8)
                  dwpalettelsize=(1<<wbitsCount)*sizeof(RGBQUAD);
    //计算位图的大小,并分配相应的内存空间,注意的是没有分配BITMAPFILEHEADER。
           dwbmdibitsize=((bitmap.bmWidth*wbitsCount+31)/8)*bitmap.bmHeight;
           fdib=GlobalAlloc(GHND,dwbmdibitsize+dwpalettelsize+sizeof(BITMAPINFOHEADER));
           lpbi=(LPBITMAPINFOHEADER)::GlobalLock(fdib);
           *lpbi=bi;//将bi中的数据写入分配的内存中。
           hdc=::GetDC(NULL);
           GetDIBits(hdc,hBitmap,0,(UINT)bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwpalettelsize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
    /*GetDIBits是最重要的函数,真正获得位图数据的工作就由它完成,它第一个参数为HDC,第二个参数为位图句柄,第三个参数为扫描行的开始行,一般为0,第四个为结束行,一般就是高度,第四个参数最重要,它表示接收数据的起始地址,这个地址一般是在调色板之后。第五个参数指的是接收BITMAPINFO结构的地址,这个结构上面没有写,它其实就是BITMAPINFO结构加上调色板信息。最后一个参数是格式。一般是DIB_RGB_COLORS*/
    //创建文件以及文件信息头
    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;//BMP类型,一定要这样写
           dwdibsize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwbmdibitsize+dwpalettelsize;//文件总长,由几个部分组成
           bmfhdr.bfSize=dwdibsize;
           bmfhdr.bfReserved1=0;
           bmfhdr.bfReserved2=0;
    bmfhdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwpalettelsize;//位图数据相对于文件头的偏移量
    //将文件信息头写入文件
    WriteFile(fh,(LPSTR)&bmfhdr,sizeof(BITMAPFILEHEADER),&dwwritten,NULL);
    //将数据写入文件,包含BITMAPINFO结构、调色板、数据
    WriteFile(fh,(LPSTR)lpbi,dwdibsize,&dwwritten,NULL);
    //关闭相关句柄
    ::GlobalUnlock(fdib);
           ::GlobalFree(fdib);
           ::CloseHandle(fh);
           return TRUE;
      

  2.   

    将bmp位图信息写入文件中,代码参考ls,网上也有很多的
      

  3.   

    hdc=::GetDC(NULL);
      GetDIBits(hdc,
    这的hdc的问题?
      

  4.   

    这段代码我用过很多次了,没有问题的,是不是你的HBITMAP句柄的问题?
      

  5.   

    如果下面这个函数不好用
    就只能说明你的句柄有问题
    BOOL SaveBitmapToFile(HBITMAP hBitmap, TCHAR* lpFileName)
    {
    HDC hDC;
    int iBits;
    WORD wBitCount;
    DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten;
    BITMAP Bitmap; BITMAPFILEHEADER bmfHdr; 
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER lpbi;
    HANDLE fh, hDib, hPal;
    HPALETTE 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 if (iBits <= 24)
    wBitCount = 24;
    else
    wBitCount = 32;
    //计算调色板大小
    if (wBitCount <= 8)
    dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD); //设置位图信息头结构
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
    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.biClrUsed         = 0;
    bi.biClrImportant      = 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,(LPBYTE)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, (BITMAPINFO *)lpbi,DIB_RGB_COLORS); //恢复调色板   
    if (hOldPal)
    {
    SelectPalette(hDC, hOldPal, TRUE);
    RealizePalette(hDC);
    ::ReleaseDC(NULL, hDC);
    }
    //创建位图文件    
    fh = CreateFile(lpFileName, 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, (LPBYTE)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    // 写入位图文件其余内容
    WriteFile(fh, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize , &dwWritten, NULL);  //清除   
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    CloseHandle(fh);
    return TRUE;
    }