登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

VC下显示位图的几种方法  

2009-07-29 19:30:15|  分类: VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

/*************************************************************/
想来想去还是不能叫做原创,毕竟里面的大部分东西都是前辈们的劳动成功
我只是收集了一下,所以还是叫学习小结的好!
转载请说明出处
如有问题欢迎和本人联系讨论:baoliangster@gmail.com
由于每次上传只能100K所以就所文件给分开了,分为DemoBitmap1.rar,DemoBitmap.rar
下载先解压DemoBitmap.rar,然后把DemoBitmap1.ra解压的内容放到入前一个解压后的文件
中,对于里面的位图文件,只能大家自己准备了,为了节省空间,我就没上传.(上传的时候
出现了错误可能有两个相同的只要选择一个就可以了。)
/*************************************************************/
VC下显示位图的几种方法
总结一下关于位图的几种用法。
说到这还是开头给大家介绍一下,有关位图的知识吧,以及对于我们比较有用的几个关于位图的结构体。
一.位图结构如下:

---- 一、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); 
 }
}


 

  评论这张
 
阅读(1199)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018