VC下显示位图的几种方法
2009-01-09 10:56
309 查看
2008-12-02 16:56
转自:http://blog.csdn.net/xyshu/archive/2008/08/20/2802162.aspx ----一、BMP文件结构 ---- 1. BMP文件组成 ---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 ---- 2. BMP文件头 ---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 ---- 其结构定义如下: typedef struct tagBITMAPFILEHEADER { WORDbfType; // 位图文件的类型,必须为BM DWORD bfSize; // 位图文件的大小,以字节为单位 WORDbfReserved1; // 位图文件保留字,必须为0 WORDbfReserved2; // 位图文件保留字,必须为0 DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 // 文件头的偏移量表示,以字节为单位 } BITMAPFILEHEADER; ---- 3. 位图信息头 BMP位图信息头数据用于说明位图的尺寸等信息。 typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // 本结构所占用字节数 LONGbiWidth; // 位图的宽度,以像素为单位 LONGbiHeight; // 位图的高度,以像素为单位 WORD biPlanes; // 目标设备的级别,必须为1 WORD biBitCount// 每个像素所需的位数,必须是1(双色), // 4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; // 位图的大小,以字节为单位 LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 DWORD biClrImportant;// 位图显示过程中重要的颜色数 } BITMAPINFOHEADER; ---- 4. 颜色表 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。RGBQUAD结构的定义如下: typedef struct tagRGBQUAD { BYTErgbBlue;// 蓝色的亮度(值范围为0-255) BYTErgbGreen; // 绿色的亮度(值范围为0-255) BYTErgbRed; // 红色的亮度(值范围为0-255) BYTErgbReserved;// 保留,必须为0 } RGBQUAD; 颜色表中RGBQUAD结构数据的个数有biBitCount来确定: 当biBitCount=1,4,8时,分别有2,16,256个表项; 当biBitCount=24时,没有颜色表项。 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; // 位图信息头 RGBQUAD bmiColors[1]; // 颜色表 } BITMAPINFO; 下面我们介绍第一种办法: //第一种方法,使用WM__CTRLCOLOR来实现 /*******************OnCtlColor中添加的代码*****************/ HBRUSH CDemoBitmapDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here //第一种实现方法 if(nCtlColor=CTLCOLOR_DLG) { return brush; } // TODO: Return a different brush if the default is not desired return hbr; } BOOL CDemoBitmapDlg::OnInitDialog() { //第一种方法,使用wm_ctlcolor来实现 CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); brush.CreatePatternBrush(&bitmap);//brush定义在头文件中CBrush burush bitmap.deleteobject(); } 第二种方法使用资源文件中导入的IDB_BITMAP来实现 第一步先在资源中导入一个位图:IDB_BITMAP1 void CDemoBitmapDlg::OnBtnBitmap() { // TODO: Add your control notification handler code here /***************显示BITMAP的第二种方法**********************/ HBITMAP hBitmap; CBitmap bitmap; CClientDC *pDC; pDC=new CClientDC(this); hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); bitmap.Attach(hBitmap); CDC CDCompatible; CDCompatible.CreateCompatibleDC(pDC);//创建兼容DC CDCompatible.Selectobject(&bitmap); /*********其它几种显示方式********/ /* pDC->BitBlt(0,0,200,200,&CDCompatible,0,0,SRCCOPY); CDCompatible.SetBkMode(TRANSPARENT); pDC->StretchBlt(0,0,352,288,&CDCompatible,0,0,352,288,SRCCOPY); CDCompatible.CreateCompatibleDC(this->GetDC()); CDCompatible.Selectobject(&bitmap); */ //选择绘图对象 BITMAP bmp; bitmap.GetBitmap(&bmp); pDC->StretchBlt(0,0,bmp.bmWidth,bmp.bmHeight,&CDCompatible,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); CDCompatible.deleteDC(); ::deleteobject(&bitmap); } 第三种方法是通过读取指定目录中的位图文件来显示(这里分别把它们显示在Picture控件和Static上面这也是大家通常要用到的): void CDemoBitmapDlg::OnBtnPic() { // TODO: Add your control notification handler code here /****************向PICTURE控件中动态添加位图****************************/ HBITMAP hBitmap; CBitmap bitmap; hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); bitmap.Attach(hBitmap); m_Pic.SetBitmap(hBitmap); } /****************在STATIC中显示位图*********************/ void CDemoBitmapDlg::OnBtnStatic() { // TODO: Add your control notification handler code here CBitmap hbmp; HBITMAP hbitmap; //将pStatic指向要显示的地方 CStatic *pStaic; pStaic=(CStatic*)GetDlgItem(IDC_IMAGE); // pStaic=(CStatic*)GetDlgItem(IDC_BUTTON1); //装载资源 MM.bmp是我的一个文件名,用你的替换 hbitmap=(HBITMAP)::LoadImage (::AfxGetInstanceHandle(),"NetFriend.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); hbmp.Attach(hbitmap); //获取图片格式 BITMAP bm; hbmp.GetBitmap(&bm); CDC dcMem; dcMem.CreateCompatibleDC(GetDC()); CBitmap *poldBitmap=(CBitmap*)dcMem.Selectobject(hbmp); CRect lRect; pStaic->GetClientRect(&lRect); //显示位图 pStaic->GetDC()->StretchBlt(lRect.left ,lRect.top ,lRect.Width(),lRect.Height(), &dcMem,0 ,0,bm.bmWidth,bm.bmHeight,SRCCOPY); dcMem.Selectobject(&poldBitmap); } /*****************向BUTTON中添加ICON*****************************/ //方法和导入其它位图类似,在这里就只做一个说明一下就是了。 HICON hIco; hIco=AfxGetApp()->LoadIcon(IDI_ICON1); m_BtnBitmap.SetIcon(hIco); 第四种读取位图文件来显示位图: void CDemoBitmapDlg::OnBtnBtmfile() { // TODO: Add your control notification handler code here /*******************通过读取位图文件来显示位图**********************/ CString strFileName; strFileName.Format("%s","NetFriend.bmp"); //成位图信息BITMAPINFO BITMAPINFO *bitmapinfo=NULL; BYTE *BmpData=NULL; CFile file;//读取位图信息 //设置文件的打开方式 if(!file.Open(strFileName,Cfile::modeRead|Cfile::typeBinary)) { return; } //BITMAP文件头结构体 BITMAPFILEHEADER BitmapHead; //读取位图文件头 if(file.Read(&BitmapHead,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER)) { MessageBox("读取文件头失败!"); return; } if(BitmapHead.bfType!=0x4d42) { MessageBox("对不起,您读取的不是位图文件!"); return; } //位图信息 BITMAPINFOHEADER BitmapInfo; if(file.Read(&BitmapInfo,sizeof(BITMAPINFOHEADER))!=sizeof(BITMAPINFOHEADER)) { MessageBox("读取位图信息失败!"); return; } if(BitmapInfo.biBitCount!=24) { MessageBox("对不起,当前程序只支持24位位图信息!"); return; } bitmapinfo=(BITMAPINFO*)new char[sizeof(BITMAPINFOHEADER)]; if(!bitmapinfo) { MessageBox("内存分配失败!"); return; } /*把BMP位图信息头中的数据读取到位图信息结构中去.*/ memcpy(bitmapinfo,&BitmapInfo,sizeof(BITMAPINFOHEADER)); /*用来得到位图文件的大小*/ DWORD dataByte=BitmapHead.bfSize-BitmapHead.bfOffBits; BmpData=(BYTE*)new char[dataByte]; if(!BmpData) { MessageBox("内存分配失败!"); delete bitmapinfo; delete BmpData; return; } if(file.Read(BmpData,dataByte)!=dataByte) { MessageBox("读取位图数据失败!"); return; } file.Close(); CClientDC *pDC=new CClientDC(this); pDC->SetStretchBltMode(COLORONCOLOR); StretchDIBits(pDC->GetSafeHdc(),200,0,BitmapInfo.biWidth,BitmapInfo.biHeight, 0,0,BitmapInfo.biWidth,BitmapInfo.biHeight,BmpData,bitmapinfo,DIB_RGB_COLORS,SRCCOPY); } 最后给大家介绍两个显示位图的特效的例子更多的特效显示(http://www.pconline.com.cn/pcedu/empolder/gj/vc/0504/608259.html): 1> 水平交错显示位图 void CListBmap::OnButton1() { // TODO: Add your control notification handler code here HBITMAP hBitmap; CBitmap cBitmap; hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); cBitmap.Attach(hBitmap); cBitmap.GetBitmap(&bitmap); int i=0,j=0; CClientDC *pDC=new CClientDC(this); CDC memDC; memDC.CreateCompatibleDC(GetDC()); memDC.Selectobject(&cBitmap); for(i=0;i<bitmap.bmHeight;i+=2) { j=i; while(j>0) { pDC->StretchBlt(0,j-1,bitmap.bmWidth,1,&memDC,0,bitmap.bmHeight-(i-j+1), bitmap.bmWidth,1,SRCCOPY); pDC->StretchBlt(0,bitmap.bmHeight-j,bitmap.bmWidth,1,&memDC,0,i-j, bitmap.bmWidth,1,SRCCOPY); j-=2; } Sleep(50); } } 2>雨点显示: void CListBmap::OnButton2() { // TODO: Add your control notification handler code here HBITMAP hBitmap; CBitmap cBitmap; hBitmap=(HBITMAP)::LoadImage(::AfxGetInstanceHandle(),"NetFriend.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); cBitmap.Attach(hBitmap); cBitmap.GetBitmap(&bitmap); int i=0,j=0; CClientDC *pDC=new CClientDC(this); CDC memDC; memDC.CreateCompatibleDC(GetDC()); memDC.Selectobject(&cBitmap); for ( i=0; i<=bitmap.bmHeight; i++ ) { for ( j=0; j<=bitmap.bmHeight-i; j++ ) pDC->StretchBlt( 0,j, //目标设备逻辑横、纵坐标 bitmap.bmWidth,1, //显示位图的像素宽、高度 &memDC, //源位图设备情境对象 0,bitmap.bmHeight-i, //源位图的起始横、纵坐标 bitmap.bmWidth,1, //源位图的像素宽、高度 SRCCOPY); Sleep(20); } } |
相关文章推荐
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- VC下显示位图的几种方法(本人未测试)
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- VC下显示位图的几种方法
- vc 加载bmp位图并显示的方法
- vc中显示位图、图标的方法
- VC 背景填充位图的几种方法
- VC++图片控件(Picture Control)显示资源位图(BMP)、文件位图(BMP)、其它格式文件图片(JPG\PNG\BMP)的方法
- VC 背景填充位图的几种方法
- VC 背景填充位图的几种方法
- VC打开并缩放显示位图(.BMP)文件的方法
- VC中使用MFC显示位图的方法
- MFC显示位图的几种方法
- vc 加载bmp位图并显示的方法
- MFC显示位图的几种方法