void CPacsShowView::SaveBmpFormat(CString strFileName)
{ //m_PopDlg.ShowWindow(SW_HIDE);
CRect rtTemp,rtTemp1;
CDC dc;
dc.CreateDC("DISPLAY",NULL,NULL,NULL);        CMainFrame *pMain=(CMainFrame *)AfxGetMainWnd(); rtTemp1 = pMain->GetToolBar2(); GetClientRect(&rtTemp); rtTemp.left = 5; rtTemp.top =rtTemp1.bottom;

//CGraphics bm; CBitmap bm;

int Width=GetSystemMetrics(SM_CXSCREEN);

int Height=GetSystemMetrics(SM_CYSCREEN);

//获得Client Area
bm.CreateCompatibleBitmap(&dc,Width,Height);

CDC tdc;

tdc.CreateCompatibleDC(&dc);

//选择存放的地方,当tdc结构改变的时候,bm也随之改变

CBitmap*pOld=tdc.SelectObject(&bm); 



//tdc现在的值改变了
tdc.BitBlt(rtTemp.left,rtTemp.top,rtTemp.Width(),rtTemp.Height(),&dc,rtTemp.left,rtTemp.top,SRCCOPY);


//选择一个pOld Pointer to tdc
tdc.SelectObject(pOld);  

BITMAP btm;

bm.GetBitmap(&btm); //Fills a BITMAP structure with information about the bitmap

DWORD size=btm.bmWidthBytes*btm.bmHeight;

LPSTR lpData = NULL,lpDataSwap =NULL;

if (btm.bmBitsPixel <= 16) 
{
  //btm.bmBitsPixel  大于24位的以后考虑
 //保存旧的size;
DWORD oldsize =size; 

//开辟内存空间(<24 Bits)
lpDataSwap = (LPSTR)GlobalAlloc(GPTR,oldsize); 
DWORD dwTemp =0;
while (dwTemp<oldsize)
{
lpDataSwap[dwTemp] = 0xf;
dwTemp++;
}

//lpDataSwap得到bm的Bits数据
        DWORD dwResult = bm.GetBitmapBits(oldsize,lpDataSwap); //得到新的WidthBytes,size,bmBitsPixel long  newWidthBytes = WIDTHBYTES(24 *btm.bmWidth); size = newWidthBytes*btm.bmHeight; btm.bmBitsPixel =24; //开辟内存空间(24 Bits)
lpData=(LPSTR)GlobalAlloc(GPTR,size);
LPSTR lpTempData =lpData; //保存lpTemp

LPSTR lpTempSwap = lpDataSwap;

//计算了循环次数
DWORD dwCount = oldsize/2;

WORD *pSrc = (WORD*)lpDataSwap; BYTE *pDst = (BYTE *)lpData;
WORD  wTemp =0;

for (DWORD dwStart=0;dwStart<dwCount;dwStart++)
{
wTemp = *pSrc;

wTemp = *pSrc & 0x7C00;
*pDst++ = (BYTE) wTemp>>10;
wTemp = *pSrc & 0x03E0;
*pDst++ = (BYTE) wTemp >>5;
wTemp = *pSrc & 0x001F;
*pDst++ = (BYTE) wTemp;

}
lpData =lpTempData;

lpDataSwap =lpTempSwap;

GlobalFree(lpTempSwap); DeleteObject(bm);

BOOL breslut =bm1.CreateBitmap(btm.bmWidth,btm.bmHeight,1,24,lpData);
DWORD dwSize =bm.SetBitmapBits(size,lpData);



}

else lpData=(LPSTR)GlobalAlloc(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;
int iResult = GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);
static int filecount=0;
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(strFileName,CFile::modeCreate|CFile::modeWrite)){
bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData,size);
bf.Close();
}
GlobalFree(lpData);
DeleteObject(&bm);
AfxMessageBox("保存完毕!");

解决方案 »

  1.   

    biBitCount:16->RGB565
    biBitCount:15->RGB555
    biBitCount:24->RGB24
    biBitCount:32->RGB32
    BITMAPINFOHEADER 不是可以得到这些信息么?
      

  2.   

    biBitCount:15?可以等于15吗?好像都是16
    Direct draw可以判断PixelFormat是否为565
      

  3.   

    if (btm.bmBitsPixel == 16 ) 
    {

    DWORD oldsize =size; 

    //开辟内存空间(<24 Bits)
    lpDataSwap = (LPSTR)GlobalAlloc(GPTR,oldsize); 
    DWORD dwTemp =0;
    while (dwTemp<oldsize)
    {
    lpDataSwap[dwTemp] = 0xf;
    dwTemp++;
    }

    //lpDataSwap得到bm的Bits数据
    DWORD dwResult = bm.GetBitmapBits(oldsize,lpDataSwap);

    //得到新的WidthBytes,size,bmBitsPixel

    long  newWidthBytes = WIDTHBYTES(24 *btm.bmWidth);

    size = newWidthBytes*btm.bmHeight;

    btm.bmBitsPixel =24;

    //开辟内存空间(24 Bits)
    lpData=(LPSTR)GlobalAlloc(GPTR,size);


    LPSTR lpTempData =lpData; //保存lpTemp

    LPSTR lpTempSwap = lpDataSwap;

    //计算了循环次数
    DWORD dwCount = oldsize/2;

    WORD *pSrc = (WORD*)lpDataSwap;

    BYTE *pDst = (BYTE *)lpData;
    WORD  wTemp =0;

    //RGB
    //0xF800、0x07E0、0x001F
    //5 6 5

    for (DWORD dwStart=0;dwStart<dwCount;dwStart++)
    {
    wTemp = *pSrc;

    wTemp = *pSrc & 0xF800;
    *pDst++ = (BYTE) wTemp>>11;
    wTemp = *pSrc & 0x07E0;
    *pDst++ = (BYTE) wTemp >>5;
    wTemp = *pSrc & 0x001F;
    *pDst++ = (BYTE) wTemp;

    }
    lpData =lpTempData;

    lpDataSwap =lpTempSwap;

    GlobalFree(lpTempSwap);







    }
    谢谢高人的指点,我已经解决了,贴出16 to 24的贴子
      

  4.   

    16 to24 32 to 24 if (btm.bmBitsPixel == 16 ) 
    {

    DWORD oldsize =size; 

    //开辟内存空间(<24 Bits)
    lpDataSwap = (LPSTR)GlobalAlloc(GPTR,oldsize);  DWORD dwTemp =0;

    //lpDataSwap得到bm的Bits数据
    DWORD dwResult = bm.GetBitmapBits(oldsize,lpDataSwap);

    //得到新的WidthBytes,size,bmBitsPixel

    long  newWidthBytes = WIDTHBYTES(24 *btm.bmWidth);

    size = newWidthBytes*btm.bmHeight;

    btm.bmBitsPixel =24;

    //开辟内存空间(24 Bits)
    lpData=(LPSTR)GlobalAlloc(GPTR,size);


    LPSTR lpTempData =lpData; //保存lpTemp

    LPSTR lpTempSwap = lpDataSwap;

    //计算了循环次数
    DWORD dwCount = oldsize/2;

    WORD *pSrc = (WORD*)lpDataSwap;

    BYTE *pDst = (BYTE *)lpData;
    WORD  wTemp =0;

    //RGB
    //0xF800、0x07E0、0x001F
    //5 6 5

    for (DWORD dwStart=0;dwStart<dwCount;dwStart++,pSrc++)
    {
    wTemp = *pSrc;

    wTemp = *pSrc & 0xF800;
    *pDst++ = (BYTE) wTemp>>11;
    wTemp = *pSrc & 0x07E0;
    *pDst++ = (BYTE) wTemp >>5;
    wTemp = *pSrc & 0x001F;
    *pDst++ = (BYTE) wTemp;


    }
    lpData =lpTempData;

    lpDataSwap =lpTempSwap;

    GlobalFree(lpTempSwap);

    }
    else if (btm.bmBitsPixel == 32)
    {

    DWORD oldsize =size; 

    //开辟内存空间(32 Bits)
    lpDataSwap = (LPSTR)GlobalAlloc(GPTR,oldsize);  DWORD dwTemp =0;

    //lpDataSwap得到bm的Bits数据
    DWORD dwResult = bm.GetBitmapBits(oldsize,lpDataSwap);

    //得到新的WidthBytes,size,bmBitsPixel

    long  newWidthBytes = WIDTHBYTES(24 *btm.bmWidth);

    size = newWidthBytes*btm.bmHeight;

    btm.bmBitsPixel =24;

    //开辟内存空间(24 Bits)
    lpData=(LPSTR)GlobalAlloc(GPTR,size);


    LPSTR lpTempData =lpData; //保存lpTemp

    LPSTR lpTempSwap = lpDataSwap;

    //计算了循环次数
    DWORD dwCount = oldsize/4;

    DWORD *pSrc = (DWORD*)lpDataSwap;

    BYTE *pDst = (BYTE *)lpData;

    DWORD  wTemp =0;

    //RGB //0xFF0000、0xFF00、0xFF

    for (DWORD dwStart=0;dwStart<dwCount;dwStart++,pSrc++)
    {
    wTemp = *pSrc;

    wTemp = *pSrc & 0xFF0000;
    *pDst++ = (BYTE) wTemp>>16;
    wTemp = *pSrc & 0xFF00;
    *pDst++ = (BYTE) wTemp >>8;
    wTemp = *pSrc & 0xFF;
    *pDst++ = (BYTE) wTemp;

    }
    lpData =lpTempData;

    lpDataSwap =lpTempSwap;

    GlobalFree(lpTempSwap);

    }