显示一个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的位图都可以试试吧
各位大侠指点一下。
第二种方法是:创建与设备兼容的内存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的位图都可以试试吧
各位大侠指点一下。
解决方案 »
- 子对话框嵌入父对话框中,且双击可脱离父对话框,再双击还原(出错了)
- 问个ReadFile问题,他读缓存是不是按unsigned char读的
- 怎么初始化设置codejock的自动隐藏功能?
- 100分求助GDI+保存1位tiff的源码,在线等
- 请大侠们帮忙
- 怎么在vc中实现对文本文件中内容的读取,并把读到的内容放在内存DC映射的现成做好的位图上?
- 寻人启事:congxiaojiuben(从小就笨),有知道的送分
- win32——程序员求爱的创意程序
- vs2013有自带的activex调试容器吗
- 初学者问题:得到单击CListBox某行的内容。
- 如何让下拉框随鼠标位置显示为平面或三维。
- 困惑,mfc 消息产生与接收
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);