• 在VC中显示和处理图片的方法


    落鹤生 发布于 2011-10-21 09:12 点击:344次 
    来自:blog.csdn.net/mengaim_cn
    几种用GDI画图的方法介绍。
    TAG: GDI  
     

    法1:这个方法其实用的是一本经典vc图像处理的书上的有关读取位图的函数库,

    当没有这个函数库时,就没有太多的实用价值。
    这种方法直接用的是读取和显示bmp图片的函数库
    首先要得到要显示区域的位置:
      CWnd* pWnd=GetDlgItem(IDC_BMP);
      RECT rect;
      pWnd->GetClientRect(&rect);
      CDC* pDC=pWnd->GetDC();
    然后调用函数库
      //获取DIB图像的宽度
      int cxDIB=(int)::DIBWidth(lpDIB);
      //获取DIB图像的高度
      int cyDIB=(int)::DIBHeight(lpDIB);
    最后也是调用函数库
            //调用PaintDIB输出图像
     ::PaintDIB(pDC->m_hDC,&rect,m_hDIB,&rcDIB,NULL); 
    最要释放资源
                    ReleaseDC(pDC);


    --------------------------------------------------------------------------------

    法2:
    这种方法是直接在屏幕上画图,当然,由于是一点一点的画的,所以,速度会慢些。
    首先要得到要显示区域的位置:
      CWnd* pWnd=GetDlgItem(IDC_BMP);
      CDC* pDC=pWnd->GetDC();
    然后
                    pDC->SetPixel(iw,ih,RGB(r,g,b));
    最要释放资源
                    ReleaseDC(pDC);


    ------------------------------------------------------------------------------------

    法3:
    这种方法是在内存中开辟一个空间,然后也用SetPixel的方法往内存中写数据,最后可以一次性地把数据显示在屏幕上。当然,从描述上就知道,这种方法比法2要快些,但是,由于使用SetPixel,一个点一个点的写数据,也会有些慢的。

    首先要得到要显示区域的位置:
      CWnd* pWnd=GetDlgItem(IDC_BMP);
      CDC* pDC=pWnd->GetDC();
    然后
     CDC memdc;
     CBitmap m_bitmap,*m_pOldBitmap;

     memdc.CreateCompatibleDC(pDC);
     m_bitmap.CreateCompatibleBitmap(pDC,lWidth,lHeight);
     m_pOldBitmap=memdc.SelectObject(&m_bitmap);
    然后,就可以改变内存中的数据了
            memdc.SetPixel(iw,lHeight-ih,RGB(nrgb,nrgb,nrgb));
    将结果显示出来
     pDC->StretchBlt(0,0,rect.right-rect.left,rect.bottom-rect.top,&memdc,
      0,0,lWidth,lHeight,SRCCOPY);
    最后释放资源
     memdc.SelectObject(m_pOldBitmap);
     m_bitmap.DeleteObject();
     ReleaseDC(pDC);

    -----------------------------------------------------------------------------------

    法4:
    这种方法挺不错的,一定要好好看看:)
    这应该是比法2和法3都快的方法了,因为其是直接在内存中分配一个区域,直接用操作内存区域的方法去操作它,等操作完成后在一次写到屏幕上。
    首先,得到要显示的区域
       CWnd* pWnd=GetDlgItem(IDC_IMG);
       CDC *theDC=pWnd->GetDC();
       CRect clientRect;
       pWnd->GetClientRect(clientRect);
    然后,写头文件
       BITMAPINFOHEADER bmiHeader;
       bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
       bmiHeader.biWidth = m_width;
       bmiHeader.biHeight = m_height;
       bmiHeader.biPlanes = 1;
       bmiHeader.biBitCount = 24;
       bmiHeader.biCompression = BI_RGB;
       bmiHeader.biSizeImage = 0;
       bmiHeader.biXPelsPerMeter = 0;
       bmiHeader.biYPelsPerMeter = 0;
       bmiHeader.biClrUsed = 0;
       bmiHeader.biClrImportant = 0;
    现在就可以显示出图像数据在屏幕上了
       // now blast it to the CDC passed in.
       // lines returns the number of lines actually displayed
       int lines = StretchDIBits(theDC->m_hDC,
          left, top,
          bmiHeader.biWidth,
          bmiHeader.biHeight,
          0,0,
          bmiHeader.biWidth,
          bmiHeader.biHeight,
          tmp,
          (LPBITMAPINFO)&bmiHeader,
          DIB_RGB_COLORS,
          SRCCOPY);
    注意呀,其中的tmp的类型是BYTE* ,也就是说其是指向一块内存区首地址,只要这块内存区中放的数据是BMP位图中的数据区的格式,就可以了。也就是说每行元素都是32 bit(4 byte)的整数倍。

    有了这种方法,可以说,可以直接用分配内存的函数先分配一个内存区域,然后,用memcpy将一个内存中的内容复制到另一个内存中,对其处理后,再显示出来。

    最后别忘了释放资源
       ReleaseDC(theDC);

    ------------------------------------------------------------------------
    另外,获得整个对话框的CDC,不好意思,不知道CDC是什么
      CPaintDC dc(this);
      CDC *theDC=&dc;

    (mengaim_cn)
     
    本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201110/15172.html]
     
  • 相关阅读:
    element ui el-date-picker 判断所选时间是否交叉
    MDN中的箭头函数!!!
    es6 解构
    element ui 实现可编辑表格
    节流 防抖。。。。深入理解
    element ui 表格对齐方式,表头对齐方式
    纯html + css 导航栏
    PHP 1
    apache 建立虚拟主机
    Can't connect to local MySQL server through socket '/tmp/mysql.sock'
  • 原文地址:https://www.cnblogs.com/lidabo/p/3702031.html
Copyright © 2020-2023  润新知