zoukankan      html  css  js  c++  java
  • VC下显示位图的几种方法

    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);
    }
    最后给大家介绍两个显示位图的特效的例子更多的特效显示

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

  • 相关阅读:
    Docker的历史
    IP路由基础
    Docker的基础知识(二)
    Docker的基础知识(一)
    CentOS7下安装部署“zabbix”
    使用amoeba实现mysql读写分离
    ?? 运算符(C# 参考)
    ?? 运算符(C# 参考)
    knockout,change事件
    knockout,change事件
  • 原文地址:https://www.cnblogs.com/Jade2009/p/1374846.html
Copyright © 2011-2022 走看看