落鹤生 发布于 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]
 

在VC中显示和处理图片的方法的更多相关文章

  1. vc中调用Com组件的方法详解

    vc中调用Com组件的方法详解 转载自:网络,来源未知,如有知晓者请告知我.需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGet ...

  2. VC中调用COM组件的方法(转载)

    原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...

  3. Android Device Chooser中显示Target unknown解决方法

    手机插在电脑上准备调试程序来着,通过eclipse运行时,弹出的Android Device Chooser中显示设备名是?????,Target未知,无法继续运行. 可以通过以下步骤解决(Ubunt ...

  4. vc 中调用COM组件的方法

    需求:1.创建myCom.dll,该COM只有一个组件,两个接口:   IGetRes--方法Hello(),   IGetResEx--方法HelloEx() 2.在工程中导入组件或类型库  #im ...

  5. 在VC中创建DLL文件的方法步骤

    一.Win32动态链接库 1.制作的步骤: (1)新建WIN32 Dynamic-link Library工程,工程名为MyDll,选择A simple DLL project类型. (2)MyDll ...

  6. VC中获取窗口句柄的各种方法

    AfxGetMainWndAfxGetMainWnd获取自身窗口句柄HWND hWnd = AfxGetMainWnd()->m_hWnd; GetTopWindow函数功能:该函数检查与特定父 ...

  7. VC++中list::list的使用方法总结

    本文主题 这几天在做图像处理方面的研究,其中有一部分是关于图像分割方面的,图像目标在分割出来之后要做进一步的处理,因此有必要将目标图像的信息保存在一个变量里面,一开始想到的是数组,但是马上就发现使用数 ...

  8. VC中常见API函数使用方法(经验版)

    ***********************************************声明*************************************************** ...

  9. Excel中显示长数字的方法

    主要有以下三种方法: 1.先设置为文本格式,再粘贴2.在另一列输入=CONCATENATE(A1),双击此格右下角得到全部数值,再格式化为文本粘贴回去3.选中数据列,点数据-分列,下一步-下一步,选中 ...

随机推荐

  1. 能"干掉"苹果的中国"黑客"

    他是全球发现苹果漏洞最多的人,他曾穷的住在小黑屋,他经常接到国家安全部门的电话,他差点堵住周鸿祎的路,他是谁? 无名英雄 我们最终还是没有见到吴石本人,即便他的生意合伙人刘盛(化名)已经应承了帮我们牵 ...

  2. 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 管理NHibernate二级缓存 NHibernate二级缓存由ISessionF ...

  3. 请求--拦截器--action经过

    引用我这里想知道的是同名的多个参数,会被自动的放置在List或者数组中,我想知道是怎么实现的,因为取一个参数和取多个同名的参数是不同的方法: 一个是request.getParameter 一个是re ...

  4. zoj 3716 Ribbon Gymnastics (思维数学题)

    题目 以四个顶点为圆心画圆,圆面积不能重合,求四个圆的直径和最大是多少. #define _CRT_SECURE_NO_WARNINGS #include<string.h> #inclu ...

  5. oracle的全文索引

    1.查看oracle的字符集 SQL> select userenv('language') from dual; USERENV('LANGUAGE') ------------------- ...

  6. 220 DIV2 B. Inna and Nine

    220 DIV2 B. Inna and Nine input 369727 output 2 input 123456789987654321 output 1 题意:比如例子1:369727--& ...

  7. 李洪强iOS开发之OC[017]函数和方法的区别

    // //  main.m //  15 - 函数和对象的方法的区别 // //  Created by vic fan on 16/7/12. //  Copyright © 2016年 李洪强. ...

  8. lintcode :Remove Duplicates from Sorted Array II 删除排序数组中的重复数字 II

    题目: 删除排序数组中的重复数字 II 跟进“删除重复数字”: 如果可以允许出现两次重复将如何处理? 样例 给出数组A =[1,1,1,2,2,3],你的函数应该返回长度5,此时A=[1,1,2,2, ...

  9. MySQL 建表字段长度的限制

    脑补,varchar(N),N指的是最大字符数,不是字节数. 先上测试说明:   在MySQL建表时,遇到一个奇怪的现象: root@localhost : test 10:30:54>CREA ...

  10. QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数

    QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 分类: QT2009-10-28 13:33 17695人阅读 评论(13) 收藏 举报 qtapplicationwindowse ...