1.先用BitBlt取得原始bmp文件中的某一块。
-------------------------------------------------------------------
CBitmap*   bmp=new CBitmap;   
HBITMAP   hbmp=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),path, 
IMAGE_BITMAP,0,0,LR_LOADFROMFILE);   
bmp->Attach(hbmp);
//CDC对象生成
CDC *p_MDC1 = new CDC;   
CDC *p_MDC2 = new CDC;//CBitmap指针对象生成
CBitmap *pOldBt1, *pOldBt2;   
CBitmap *bmPtr = new CBitmap;CClientDC dc(NULL);        
p_MDC2->CreateCompatibleDC(&dc);
pOldBt2=p_MDC2->SelectObject(/*pBitmap*/bmp);
p_MDC1->CreateCompatibleDC(&dc);         //生成新位图bmPtr->CreateCompatibleBitmap(&dc,divWidth,divHeight);
         //将新位图选入CDC对象中
pOldBt1=p_MDC1->SelectObject(bmPtr); 
p_MDC1->BitBlt(0, 0, divWidth, divHeight, p_MDC2,cx,cy,SRCCOPY); p_MDC1->SelectObject(pOldBt1);   
p_MDC1->DeleteDC();   
p_MDC2->SelectObject(pOldBt2);   
p_MDC2->DeleteDC();
         //返回CBitmap对象
BITMAP   bitmap;     
  bmPtr->GetBitmap(&bitmap);
HBITMAP   hbit=(HBITMAP)(*bmPtr);
SaveBmp(hbit,"test3.bmp");
---------------------------------------------------------------2。然后调用SaveBmp将分割后的文件保存到本地。
------------------------------------------------------------------------
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("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;    //wBitCount   =   8;     
  GetObject(hBitmap,   sizeof(Bitmap),   (LPSTR)&Bitmap);   
  bi.biSize =   sizeof(BITMAPINFOHEADER);   
  bi.biWidth =   Bitmap.bmWidth;   
  bi.biHeight =   Bitmap.bmHeight;   
  bi.biPlanes =   1;   
  bi.biBitCount =   wBitCount=8;   
  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;   
  }   
----------------------------------------------------------------------
原始文件是8位的,保存之后为24位的了,我把保存参数重新设置为8位,颜色就失真了,谁知道?谢谢。

解决方案 »

  1.   

    我的目的是想把内存中的bmp图像原封不动地读取回来,有其他办法吗?
      

  2.   

    保存成8位的时候,有没有把调色板写入文件
    还有已经写了文件头、写其余内容时不是dwDIBSize吧
    // 写入位图文件头
    WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    // 写入位图文件其余内容
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
      

  3.   

    dwPaletteSize:调色板字节数为0,好像没有调色板。如果没有调色板,bmp图像也是黑白的,该怎么处理?
      

  4.   

    24位bmp中没有调色板,故出来的是清晰的图像,8位bmp里面有调色板,上面的SaveBmp地调色板处理好像是针对24位的,谁能帮我修改一下,对于尚8位bmp?
      

  5.   

    你这是获取系统默认的调色板hPal = GetStockObject(DEFAULT_PALETTE); 
    并没有获取你载入的bmp的调色板