API绘画入门教程 GDI及GDI+ 使用入门教程 准备工作

  勇芳 2018-6-4 10925

电脑屏幕上所有能看到的,全是电脑绘画的结果,我们写的软件,要么系统负责绘画,要么就自己用代码绘画。

用电脑绘画(编程),不管你用什么编程语言,到最后都是用API绘画,我们可以抛开编程语言本身,直接使用API绘画,会效率更高、功能更丰富。

绘画,不管现实中的,还是电脑里的编程其实很简单的事,至于画的漂亮与否,就看艺术天赋和功力了,不扯作品,这里扯会操作。

现实中,拿张纸,找个笔,就可以在那里瞎画,其实电脑里编程,也是如此简单,定义个纸和笔,打打键盘,就可以画出来了。

编程绘图,微软起了个名词加:GDI ,后来出了个增加版叫 GDI+ ,名称是什么不重要,重要的是知道这个名即可。

当然还有个 3D绘图的,那个不是本教程之内。

为了方便使用,为 FreeBasic语言封装了类,可以进勇芳编程群里下载例题,其它语言可以参考下面教程,自己也能写出来。

GDI 和GDI+ 非常丰富,本类只是封装了最常用的部分,可以自己扩建为无限的可能。

QQ截图20180604114706.jpg

以下是我肤浅的理解和俗话表述,只为编程新手入门,若有不对的地方,敬请高手们批评指正,避免带新手走了弯路。

一、基础概念(必须了解,非常重要,理解后,后面操作就不难了)

 在现实里绘画,我们需要 纸、笔,还需要涂颜色的刷子,遇到字,可以用印章印

 在编程里,和现实一样,我们同样要 纸、笔、刷、字  ,所不同的是,编程里只是用变量来表示

 1,纸:或称画板,可以是电脑里的桌面、某个软件窗口、某个窗口里的控件,想画那里,就变量设那里

Dim nDC as hDC  '设置画板变量,类型 hDC 就是目标纸张或叫画板
nDC=GetDC(0)     '直接把桌面当画板,就画在桌面上了,可以用来截图,要是画上内容,操作系统在画桌面,会被覆盖掉。
nDC=GetDC(窗口或控件句柄)  '在某个窗口或控件里画画
......画画代码
ReleaseDC  窗口或控件句柄,nDC  ‘销毁画板,用后必须销毁,在编程里,有创建,必须有销毁,不然会消耗大量系统资源,轻则占内存大运行慢,重则软件崩溃’

 2,笔、刷、字(GDI 已经默认分配,GDI+ 则必须创建)

QQ截图20180604125258.jpg

3,图片 ,这也是必须要有的,图片可以从文件里或软件资源里读取,然后贴上去。

二、 准备工作(废话不说,直接上代码)

1,临时的直接画画(会被操作系统刷新掉,因为系统也在画,被其它窗口覆盖后移开,系统就开始画了)

Dim nDC as hDC       '准备画板
Dim tFont As HFONT   '准备字
Dim nPen As HPEN     '准备笔
Dim nBrush As HBRUSH '准备刷子
nDC=GetDC(窗口或控件句柄)  '在某个窗口或控件里画画

.........一大批画画 

ReleaseDC 窗口或控件句柄,nDC    ‘用后一定要销毁’
If tFont Then DeleteObject tFont
If nPen Then  DeleteObject nPen    '画笔
If nBrush Then DeleteObject nBrush

2,永久性画画(窗口自绘或控件自绘)

Function FORM1_WM_PAINT ( .... 这里是由操作系统,通知窗口,要重新画画了。
  Dim nDC as hDC       '准备画板
  Dim tFont As HFONT   '准备字
  Dim nPen As HPEN     '准备笔
  Dim nBrush As HBRUSH '准备刷子
  Dim ps As PAINTSTRUCT '绘画范围
  nDC = BeginPaint(系统通知来的窗口或控件句柄, @ps) '只有在WM_PAINT使用,比 GetDC 绘图效率高的多
  
  .........一大批画画
  
  EndPaint(窗口或控件句柄,nDC) '完成绘图并且销毁句柄
If tFont Then DeleteObject tFont
If nPen Then  DeleteObject nPen    '画笔
If nBrush Then DeleteObject nBrush 
   Function = True    '返回允许,告诉操作系统,这个我自己画了,不需要系统来画。
End Function

3,缓存加速技术(可选的)每一句绘图命令,将直接输出到屏幕,内容多了就造成绘画缓慢,我们需要加速,执行完全部再输出到屏幕。

不用缓存加速,绘画内容多点,就会卡的,因此,不要嫌弃麻烦,尽量使用这技术

{这里是GDI的准备代码}来自上面的代码,就不重复写了,那样比较乱
  Dim rc As Rect,m_nWidth  As Long,m_nHeight As Long,m_hBmp As HBITMAP,m_Dc As hDC,m_hOldBmp As HBITMAP  '声明必要变量
  GetClientRect(窗口或控件句柄, @rc) ‘获取窗口的矩形’
  m_nWidth = (rc.Right - rc.Left) + 1  ‘获取窗口的高度宽度,需要+1’
  m_nHeight = (rc.Bottom - rc.Top) + 1
      ' // 创建一个兼容的位图
      m_hBmp = CreateCompatibleBitmap(m_nDC, m_nWidth, m_nHeight)
      ' // 创建兼容的设备上下文
      m_Dc = CreateCompatibleDC(m_nDC)
      ' // 将位图选择到兼容的设备上下文中
      If m_Dc Then m_hOldBmp = SelectObject(m_Dc, m_hBmp)
      
  .........一大批画画,画到 m_DC 里,这是缓存

  BitBlt nDC,0,0,m_nWidth,m_nHeight,m_Dc,0,0,SrcCopy '将内存DC,输出到窗口,至此输出到屏幕,让我们看到了
   ' // 恢复原始位图
   SelectObject(m_Dc, m_hOldBmp)
   ' // 销毁位图和内存设备上下文
   DeleteObject m_hBmp
   DeleteDC m_Dc
{这里是GDI的清理代码}

4,GDI+ 初始化和准备工作(GDI+ 可以选,没用到,就可以不写,要用就写了。)

GDI+ 比GDI最大的好处是反锯齿,让画画更好看舒服,但速度就变慢了。还有支持更多格式的图片文件和渐变填色,一般尽量用 GDI ,特殊需要再用 GDI+

 GDI+ 初始化(VisualFreeBasic 在工程属性里选择启用GDI+ ,不需要写代码)

======写在软件的最开始处========== VisualFreeBasic 不需要写这些代码
   Dim gdipToken As ULONG_PTR
   Dim gdipsi As GdiplusStartupInput
   gdipsi.GdiplusVersion = 1
   GdiplusStartup( @gdipToken, @gdipsi, Null )  ‘通知系统,软件要用GDI+’
   
======写在关闭软件处的代码==========
   GdiplusShutdown( gdipToken ) ‘关闭GDI+库,必须清理,避免浪费系统资源’

准备工作

{这里是GDI的准备代码}
{这里是缓存加速准备代码}
nGpDC As GpGraphics Ptr 'GDI+ 的DC
nGpPen As GpPen Ptr    'GDI+ 笔 
nGpBrush As GpBrush Ptr  'GDI+ 刷
nGpimage As GpImage Ptr  'GDI+ 位图,用来画图
GdipCreateFromHDC(m_Dc, @nGpDC)  ‘把GDI+ 对应为 GDI的DC,这样画的内容就立即到 那里了,这里是用 缓存DC’
GdipSetSmoothingMode nGpDC,SmoothingModeAntiAlias  ‘设置GDI+为消除锯齿模式,用GDI+就是看中反锯齿’

.........一大批画画,画到GDI+ 或 GDI 里

   If nGpDC Then GdipDeleteGraphics(nGpDC)   '下面是清理工作
   If nGpPen Then GdipDeletePen nGpPen
   If nGpBrush Then GdipDeleteBrush nGpBrush 'GDI+ 刷
   If nGpimage Then GdipDisposeImage nGpimage
{这里是缓存加速清理代码}
{这里是GDI的清理代码}

5,使用类,准备和清理工作,比较烦,但必须要写,可以建立个类,就方便了,以上所有的,只需要一句(包括GDI+)

FB的类在勇芳编程群里下载,其它语言需要你自己创建。

临时画画

Dim gg As yGDI = 窗口或控件句柄

永久画画(是指 WM_PAINT 消息里,假如临时画画用这个,是画不出来的)

Dim gg As yGDI = yGDI(窗口或控件句柄,底色,True)

准备工作做好了,我们就开始实战吧,

请看 实战GDI 篇GDI+实战篇

API画画流程:

{这里是GDI的准备代码}
{这里是缓存加速准备代码}
{这里是GDI+准备代码}

...这里才是我们自己写的代码,要画的内容....

{这里是GDI+清理代码}
{这里是缓存加速清理代码}
{这里是GDI的清理代码}
因国家互联网安全管理要求,关闭回帖功能。大家需要留言,请使用【勇芳软件客服】即时联系勇芳点此打开->>勇芳软件客服
返回
联系勇芳
发新帖 搜索 反馈 回顶部