显示一个bmp图像文件,有两种思路,一种方法是:创建与设备兼容的内存DC,再调用loadimage,然后再选入内存DC,最后调用Bitblt从内存设备上块传输到显示设备上。这种方法OK。
第二种方法是:创建与设备兼容的内存DC ,再读取bmp文件,把他的头信息,象素数据都读出来,再调用StretchDIBits,显示到内存设备DC中,最后调用Bitblt从内存设备上块传输到显示设备上。这种方法就是没有反映,为什么呢?
代码如下: RGBQUAD  m_ColorTable[256];
BITMAPINFO* m_bmi;
BYTE*m_pPixelData;
char m_szBMPName[_MAX_PATH];
 
BOOL LoadBMP(LPSTR szBmpFileName, int * pnBmpWidth, int*pnBmpHeight, int*pnBmpBits);#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)BOOL CDreawView::LoadBMP(LPSTR szBmpFileName, int * pnBmpWidth, int*pnBmpHeight, int*pnBmpBits)
{ FILE *fp=NULL;

    BITMAPFILEHEADER bfh;     
BITMAPINFOHEADER bih;
    int bitcount=0; 
int dataBytes=0;
int i=0; if(m_pPixelData!=NULL)
{
delete m_pPixelData;
m_pPixelData=NULL;
}
if(m_bmi!=NULL)
{
delete m_bmi;
m_bmi=NULL;
}  
   if ((fp=fopen(szBmpFileName,"rb"))==NULL)
   {
    printf("Open File Fail ");
    return FALSE;
   }
     
   if(fread(&bfh,1,sizeof(bfh),fp)!=sizeof(bfh))
 {
   printf("Error in reading file BITMAPFILEHEADER  ");
   return FALSE; 
   }   if(bfh.bfType !=0x4d42)
   {
  printf(" is not bmp image ");
  return FALSE; 
   }   if(fread(&bih,1,sizeof(bih),fp)!=sizeof(bih)) 
   {
   printf("error in reading BITMAPINFOHEAER"); 
   return FALSE;
   }    switch(bih.biBitCount)
{
case 8:
bitcount=bih.biBitCount;

m_bmi = (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER) +256*sizeof(RGBQUAD));
fseek(fp,sizeof(bfh),SEEK_SET);
fread(m_bmi,1,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD),fp);
    dataBytes=m_bmi->bmiHeader.biHeight*WIDTHBYTES(m_bmi->bmiHeader.biBitCount*m_bmi->bmiHeader.biWidth);;
    if(m_pPixelData==NULL)
 {
   m_pPixelData=new BYTE[dataBytes*sizeof(BYTE)];  
 }      if(!m_pPixelData)
 { 
    printf("allocate memory for data failed  ");
   delete m_bmi;
       return FALSE;
 }
 fread(m_pPixelData,1,dataBytes,fp);  
   for(i=0; i<256;i++)
 {
    m_ColorTable[i].rgbBlue =m_bmi->bmiColors[i].rgbBlue;
    m_ColorTable[i].rgbGreen=m_bmi->bmiColors[i].rgbGreen;
    m_ColorTable[i].rgbRed=m_bmi->bmiColors[i].rgbRed;    
 }
  fclose(fp); 
 
break; case 24:
bitcount=bih.biBitCount;

     m_bmi=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)];
         if (!m_bmi)
 {
    printf("allocte memory for  file info failed ");
    return FALSE;
 }
     memcpy(m_bmi,&bih,sizeof(BITMAPINFOHEADER));      dataBytes=bfh.bfSize-bfh.bfOffBits;
  
   m_pPixelData=new BYTE[dataBytes*sizeof(BYTE)];   
     if(!m_pPixelData)
 {
 printf("allocate memory for data failed  ");
   delete m_bmi;
       return FALSE;
 }      if(fread(m_pPixelData,1,dataBytes,fp)!=dataBytes)
 {
    printf("read image pixel data failed  ");
    delete m_bmi;
    return FALSE;  
 }
     fclose(fp); 
     break;

 default:
printf("not supported or Invalid BMP File!");
return FALSE;
}      *pnBmpWidth=m_bmi->bmiHeader.biWidth;
*pnBmpHeight=m_bmi->bmiHeader.biHeight;
*pnBmpBits=bitcount;  
//assert(dataBytes==(bitcount/8)*(*pnBmpWidth)*(*pnBmpHeight)); 

return TRUE;
}
void CDreawView::OnDraw(CDC* pDC)
{
CDreawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here HBITMAP hbm;
HDC hdcImage=NULL;

hdcImage=CreateCompatibleDC(NULL);  
//hdcImage=pDC->GetSafeHdc();
int width=0;
int height=0;
RECT m_cPicRect;
int bit=0;
/*

hbm=(HBITMAP) LoadImage(NULL,"img000.BMP",IMAGE_BITMAP,
0,0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if(!hbm) 
return ;
  BITMAP bm;
GetObject(hbm,sizeof(BITMAP),(LPVOID)&bm);
//SetRect(&m_cPicRect,0,0,bm.bmWidth,bm.bmHeight);
width=bm.bmWidth;
height= bm.bmHeight;
SelectObject(hdcImage,hbm); 
 */
  LoadBMP("img000.BMP", &width, &height, &bit);
SetStretchBltMode (hdcImage,COLORONCOLOR); 
int r2c=StretchDIBits(hdcImage, // handle to device context
             0,  // x-coordinate of upper-left corner of dest. rectangle
 0,   // y-coordinate of upper-left corner of dest. rectangle
 width,      // width of destination rectangle
 height,      // height of destination rectangle
 0,            // x-coordinate of upper-left corner of source rectangle
 0,            // y-coordinate of upper-left corner of source rectangle  
 m_bmi->bmiHeader.biWidth,     // width of source rectangle
 m_bmi->bmiHeader.biHeight,    // height of source rectangle 
                     m_pPixelData,  // address of bitmap bits
 m_bmi,        //  address of bitmap data     
 DIB_RGB_COLORS,        // usage flags
 SRCCOPY); 随便找一个24bit的位图都可以试试吧
各位大侠指点一下。

解决方案 »

  1.   

    《vc++数字图像处理》中有详细的代码,得用dibapi把。
      

  2.   

    参考一下
    CFileStatus fstatus;
    CFile file;
    LONG cb;
    HGLOBAL hGlobal;
    if(file.Open("c:\\start.bmp",CFile::modeRead)&&
    file.GetStatus("c:\\start.bmp",fstatus)&&((cb =fstatus.m_size)!= -1))
    {
    hGlobal = GlobalAlloc(GPTR,cb);
    file.ReadHuge(hGlobal,cb);
    file.Close();
    }
    BITMAPFILEHEADER *pbfh =(BITMAPFILEHEADER *)hGlobal;
    BITMAPINFOHEADER *pbih = (BITMAPINFOHEADER *)((BYTE *)hGlobal + 14);
    BYTE *pdata;
    pdata = (BYTE*)hGlobal + pbfh->bfOffBits; //指向位图的数据区。
    StretchDIBits(hdc,0,0,pbih->biWidth,pbih->biHeight,
    0,0,pbih->biWidth,pbih->biHeight,pdata,(BITMAPINFO *)pbih,DIB_RGB_COLORS,SRCCOPY);

    GlobalFree(hGlobal);