找回密码
 加入
搜索
查看: 11760|回复: 16

[图形处理] gdi和gdi+的区别?

 火.. [复制链接]
发表于 2012-4-26 11:25:51 | 显示全部楼层 |阅读模式
是不是GDIPlus.au3里面的函数就是gdi的
而GDIPlusEx.au3里面的函数就是gdi+的
发表于 2012-4-26 11:44:20 | 显示全部楼层
以前也和你一样想法,其实不是的
GDIPlus.au3和GDIPlusEx.au3里面的函数都是gdi+的
API中的图形操作才是gdi的
 楼主| 发表于 2012-4-26 13:09:21 | 显示全部楼层
回复 2# seniors


    原来是这样啊,受教了
发表于 2012-4-26 16:24:41 | 显示全部楼层
回复 2# seniors

没碰过GDI, 本来想看看 gdi和gdi+的区别!
可是, 看完帖子, 还是一头雾水啊!
发表于 2012-4-26 16:25:50 | 显示全部楼层
回复 4# user3000
我回家给大家举个例子
发表于 2012-4-26 16:31:45 | 显示全部楼层
回复 5# seniors

期待中!
解我迷惑将重赏!
发表于 2012-4-26 18:16:37 | 显示全部楼层
回复 4# user3000

转个别人说的,还是说得很清楚地:
----------------------------------------------转帖---------------------------------------------
GDI+是GDI的下一个版本,它进行了很好的改进,并且易用性更好。GDI的一个好处就是你不必知道任何关于数据怎样在设备上渲染的细节,GDI+更好的实现了这个优点,也就是说,GDI是一个中低层API,你还可能要知道设备,而GDI+是一个高层的API,你不必知道设备。例如你如果要设置某个控件的前景和背景色,只需设置BackColor和ForeColor属性。

编程模式的变化
“GDI uses a stateful model, whereas GDI+ uses a stateless”——GDI是有状态的,GDI+是无无状态的。

1、不再使用设备环境或句柄
  在使用GDI绘图时,必须要指定一个设备环境(DC),用来将某个窗口或设备与设备环境类的句柄指针关联起来,所有的绘图操作都与该句柄有关。而GDI+不再使用这个设备环境或句柄,取而代之是使用Graphics对象。与设备环境相类似,Graphics对象也是将屏幕的某一个窗口与之相关联,并包含绘图操作所需要的相关属性。但是,只有这个Graphics对象与设备环境句柄还存在着联系,其余的如Pen、Brush、Image和Font等对象均不再使用设备环境。

2、Pen、Brush,Font,Image等对象是图形对象独立的
  画笔对象能与用于提供绘制方法的图形对象分开创建于维护,Graphics绘图方法直接将Pen对象作为自己的参数,从而避免了在GDI使用SelectObject进行繁琐的切换,类似的还有Brush、Path、Image和Font等。

3、“当前位置”
  GDI绘图操作(如画线)中总存在一个被称为"当前位置"的特殊位置。每次画线都是以此当前位置为起始点,画线操作结束之后,直线的结束点位置又成为了当前位置。设置当前位置的理由是为了提高画线操作的效率,因为在一些场合下,总是一条直线连着另一条直线,首尾相接。有了当前位置的自动更新,就可避免每次画线时都要给出两点的坐标。尽管有其必要性,但是单独绘制一条直线的场合总是比较多的,因此GDI+取消这个"当前位置"以避免当无法确定"当前位置"时所造成的绘图的差错,取而代之的是直接在DrawLine中指定直线起止点的坐标。   

4、绘制和填充
  GDI总是让形状轮廓绘制和填充使用同一个绘图函数,例如Rectangle。轮廓绘制需要一个画笔,而填充一个区域需要一个画刷。也就是说,不管我们是否需要填充所绘制的形状,我们都需要指定一个画刷,否则GDI采用默认的画刷进行填充。这种方式确实给我们带来了许多不便,现在GDI+将形状轮廓绘制和填充操作分开而采用不同的方法,例如DrawRectangle和FillRectangle分别用来绘制和填充一个矩形。   

5、区域的操作
  GDI提供了许多区域创建函数,如:CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn和CreatePolyPolygonRgn等。诚然,这些函数给我们带来了许多方便。但在GDI+中,由于为了便于将区域引入矩阵变换操作,GDI+简化一般区域创建的方法,而将更复杂的区域创建交由Path接管。由于Path对象是与设备环境分离开来的,因而可以直接在Region构造函数中加以指定。

====================================================================
GDI+和GDI区别以及一些新特征

【GDI+与GDI】

1. GDI是硬件加速的,而GDI+不是的,而且GDI+2.0比GDI+更快。

2. GDI是有状态的,而GDI+是无状态的。

3. GDI绘图要使用设备环境和句柄;而GDI+全部交由Graphics类管理。

4. GDI绘图时可以使用SelectObject频繁切换图形对象,而GDI+的图形对象是独立的。

5. GDI中存在一个“当前位置”(全局区),目的是提高绘图性能;而GDI+取消了它,以避免绘图时不确定这个“当前位置”而带来非预期的错误。

6. GDI总是将画笔和画刷绑定在一起,即使不需要填充一个区域也必须指定一个画刷;而GDI+则可以使用不同的函数分开使用画笔和画刷。


【GDI+新特性】

1. 改进了颜色管理。GDI+不仅提供了更多可供选择使用的颜色,使其支持Alpha通道合成运算,而且还保持了与其他颜色的兼容性。

2. 绘图支持反锯齿。通过设置GDI+对象的相关属性,GDI+可以与相关的显示驱动程序搭配完成图形绘制时的反锯齿功能,使得绘制的图形更加平滑,美观,而整个过程是由GDI+对象自动计算完成的。

3. 提供渐变画刷。GDI+拓展了GDI的功能,提供线性渐变和路径渐变画刷来填充图形、路径和区域,甚至也可用来绘制直线、曲线等。

4. 独立的路径对象。GDI+使用Graphics对象来进行绘图操作,并将路径操作从Graphics对象分离出来,提供一个Graphics类供用户使用,用户不必担心对象会受到Graphics对象操作的影响,从而可以使用同一个操作对象进行多次的路径绘制操作。

5. 样条曲线。GDI+封装了绘制基数样条曲线和贝塞尔样条曲线的方法。

6. 变形和矩阵运算。GDI+提供了功能强大的Matrix类来实现矩阵的旋转,错切、平移、比例等变换操作,以便产生复杂的新图形。

7. 多图片格式的支持。GDI+该进了图形处理能力,通过GDI+,用户能够访问多种格式的图片文件,转换文件格式等,还能进行图像重新着色、色彩修正、消除走样等图像处理。

评分

参与人数 4金钱 +120 贡献 +13 收起 理由
502762378 + 40 + 5 学习一下
afan + 20
xms77 + 30 + 3 感谢分享GDI和GDI+的不同
user3000 + 30 + 5 Thanks a lot!

查看全部评分

 楼主| 发表于 2012-4-26 18:47:37 | 显示全部楼层
回复 7# happytc


    1、不再使用设备环境或句柄
======================
这么一说,那2楼说的就不对了

安这个说法,我原来自绘窗体用的还是gdi啊
发表于 2012-4-26 20:13:58 | 显示全部楼层
学习,虽然没看懂
发表于 2012-4-26 20:48:09 | 显示全部楼层
了解了一点GDI和GDI+的不同
发表于 2012-4-26 21:50:36 | 显示全部楼层
回复 8# kenan
我2 楼没有说错啊
发表于 2012-4-26 21:54:51 | 显示全部楼层
本帖最后由 seniors 于 2012-4-27 08:11 编辑


gdi是一定要设备DC的,没有DC,GDI无法操作
gdi+与设备无关,但最终还是要送到一定的设备上的
总之GDI+功能比GDI多
下面上源码,大家讨论讨论
修改了代码,gdi和gdi+多分了直接绘制和缓冲绘制
#include <WinAPIEx.au3>
#include <GDIPlusEx.au3>
#include <APIConstants.au3>

Opt('GUIOnEventMode', 1)
GUICreate("GDI和GDI+区别", 400, 300)
GUISetOnEvent(-3, "exitfunc")
GUICtrlCreatePic("", 0, 0, 400, 200)
$hPic = GUICtrlGetHandle(-1)
GUICtrlCreateButton("GDI绘图直接绘图", 5, 210)
GUICtrlSetOnEvent(-1, "GDIDraw")
GUICtrlCreateButton("GDI绘图缓冲刷新", 5, 240)
GUICtrlSetOnEvent(-1, "GDIDraw2")
GUICtrlCreateButton("GDI+绘图直接绘图", 205, 210)
GUICtrlSetOnEvent(-1, "GDIPlusDraw")
GUICtrlCreateButton("GDI+绘图缓冲刷新", 205, 240)
GUICtrlSetOnEvent(-1, "GDIPlusDraw2")

GUISetState()

While 1
        Sleep(100)
WEnd

Func exitfunc()
        Exit
EndFunc   ;==>exitfunc

Func GDIDraw()
        $hDC = _WinAPI_GetDC($hPic)

        ;写字符串的方式一
        $oldTextColor = _WinAPI_SetTextColor($hDC, 0xCD0091);文字颜色设置
        _WinAPI_SetBkMode($hDC, $TRANSPARENT);文字背景透明
        $hFont = _WinAPI_CreateFont(38, 0, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, '黑体')
        $oldFontObj = _WinAPI_SelectObject($hDC, $hFont);字体选择
        _WinAPI_TextOut($hDC, 10, 10, 'TextOut方式写字符串');10,10处输出文字
        _WinAPI_SelectObject($hDC, $oldFontObj);改回原来默认字体
        _WinAPI_DeleteObject($hFont);释放字体对象
        _WinAPI_SetTextColor($hDC, $oldTextColor);改回原来默认文字颜色
        
        ;写字方式二
        $tRECT = _WinAPI_CreateRect(10, 60, 300, 84);文字区域左上右下
        _WinAPI_SetBkMode($hDC, $OPAQUE);设置文字背景不透明
        _WinAPI_SetBkColor($hDC, 0x0000FF);背景颜色
        _WinAPI_DrawText($hDC, 'DrawText方式写字符串', $tRECT, $DT_LEFT);在上述区域左对齐输出文字
        
        ;绘制椭圆
        $tRECT = _WinAPI_CreateRect(10, 100, 300, 184);椭圆区域
        $hBrush = _WinAPI_CreateBrushIndirect($BS_HATCHED, 0x00A820, $HS_DIAGCROSS);椭圆填充画刷
        $hObj = _WinAPI_SelectObject($hDC, $hBrush);画刷选择
        _WinAPI_Ellipse($hDC, $tRECT);在矩形区域绘制椭圆,边框用默认画笔默认颜色,用上述画刷填充
        _WinAPI_SelectObject($hDC, $hObj);改回来原来默认填充画刷
        _WinAPI_DeleteObject($hBrush);释放画刷对象
        
        ;释放DC
        _WinAPI_ReleaseDC($hPic, $hDC)
EndFunc   ;==>GDIDraw

Func GDIDraw2()
        $hDC = _WinAPI_GetDC($hPic)
        
        $hMemDC = _WinAPI_CreateCompatibleDC($hDC);建立兼容DC,即内存中的DC
        $hBitmap = _WinAPI_CreateCompatibleBitmapEx($hDC, 400, 200, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)));创建hBitmap
        $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap);调入DC作图对象,即把图形画在$hBitmap上
        ;写字符串的方式一
        $oldTextColor = _WinAPI_SetTextColor($hMemDC, 0xCD0091)
        _WinAPI_SetBkMode($hMemDC, $TRANSPARENT)
        $hFont = _WinAPI_CreateFont(38, 0, 0, 0, $FW_NORMAL, 0, 0, 0, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $ANTIALIASED_QUALITY, $DEFAULT_PITCH, '黑体')
        $oldFontObj = _WinAPI_SelectObject($hMemDC, $hFont)
        _WinAPI_TextOut($hMemDC, 10, 10, 'TextOut方式写字符串')
        _WinAPI_SelectObject($hMemDC, $oldFontObj)
        _WinAPI_DeleteObject($hFont)
        _WinAPI_SetTextColor($hMemDC, $oldTextColor)
        
        ;写字方式二
        $tRECT = _WinAPI_CreateRect(10, 60, 300, 84)
        _WinAPI_SetBkMode($hMemDC, $OPAQUE)
        _WinAPI_SetBkColor($hMemDC, 0x0000FF)
        _WinAPI_DrawText($hMemDC, 'DrawText方式写字符串', $tRECT, $DT_LEFT)
        
        ;绘制椭圆
        $tRECT = _WinAPI_CreateRect(10, 100, 300, 184)
        $hBrush = _WinAPI_CreateBrushIndirect($BS_HATCHED, 0x00A820, $HS_DIAGCROSS)
        $hObj = _WinAPI_SelectObject($hMemDC, $hBrush)
        _WinAPI_Ellipse($hMemDC, $tRECT)
        _WinAPI_SelectObject($hMemDC, $hObj)
        _WinAPI_DeleteObject($hBrush)
        
        ;把内存DC中的内容拷贝到我们的pic对象DC中
        ;这二句注释了,设置hBitmap到pic控件别注释也能运行,而且最小化了图片还在
;~         _WinAPI_BitBlt($hDC, 0, 0, 400, 200, $hMemDC, 0, 0, $SRCCOPY)
;~         _WinAPI_DeleteObject($hBitmap)

        ;释放创建的对象及DC
        _WinAPI_SelectObject($hMemDC, $hSv)
        _WinAPI_DeleteDC($hMemDC)
        
        _WinAPI_ReleaseDC($hPic, $hDC)
        
        ;设置hBitmap到pic控件
        $oldObj = _SendMessage($hPic, 0x0172, 0, $hBitmap) ;$STM_SETIMAGE = 0x0172
        _WinAPI_DeleteObject($oldObj)
        Local $hObj = _SendMessage($hPic, 0x0173) ;$STM_GETIMAGE = 0x0173
        If $hObj <> $hBitmap Then
                _WinAPI_DeleteObject($hBitmap)
        EndIf
EndFunc   ;==>GDIDraw2

Func GDIPlusDraw()
        _GDIPlus_Startup()
        $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hPic)
        _GDIPlus_GraphicsClear($hGraphic, 0xFFCCCCCC);清空图形
        ;设置平滑
        _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
        _GDIPlus_GraphicsSetInterpolationMode($hGraphic, 7)
        
        ;drawstring方式写字
;~         _GDIPlus_GraphicsDrawString($hGraphic, '黑体', 10, 10,'黑体');一时没弄清,这怎么不能出效果了
        $hBrush = _GDIPlus_BrushCreateSolid(0xFF9100CD)
        $hFormat = _GDIPlus_StringFormatCreate()
        $hFamily = _GDIPlus_FontFamilyCreate("黑体")
        $hFont = _GDIPlus_FontCreate($hFamily, 24, 0)
        $tLayout = _GDIPlus_RectFCreate(10, 10, 0, 0)
        $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, 'DrawString方式写字符串', $hFont, $tLayout, $hFormat)
        _GDIPlus_GraphicsDrawStringEx($hGraphic, 'DrawString方式写字符串', $hFont, $aInfo[0], $hFormat, $hBrush)
        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_BrushDispose($hBrush)

        ;文字转化为路径方式写字
        $hFormat = _GDIPlus_StringFormatCreate()
        _GDIPlus_StringFormatSetAlign($hFormat, 0);0为左对齐
        $hFamily = _GDIPlus_FontFamilyCreate('Arial')
        $tLayout = _GDIPlus_RectFCreate(0, 50, 390, 30)
        $hPath = _GDIPlus_PathCreate()
        _GDIPlus_PathAddString($hPath, 'Path方式写字符串', $tLayout, $hFamily, 1, 38, $hFormat)
        $hBrush = _GDIPlus_LineBrushCreateFromRect($tLayout, 0xFF02B9EE, 0xFF004696, 1, 3)
        $hPen = _GDIPlus_PenCreate(0xFF263E57, 2, 0)
        _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush)
        _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen)
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_PathDispose($hPath)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        
        ;绘制椭圆
        $tLayout = _GDIPlus_RectFCreate(10, 100, 290, 84)
        $hBrush = _GDIPlus_LineBrushCreateFromRect($tLayout, 0x0002B9EE, 0xFF004696, 2, 3)
        $hPen = _GDIPlus_PenCreate(0xFFFFDD00, 1, 0)
        _GDIPlus_GraphicsDrawEllipse($hGraphic, 10, 100, 290, 84, $hPen)
        _GDIPlus_GraphicsFillEllipse($hGraphic, 10, 100, 290, 84, $hBrush)
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_BrushDispose($hBrush)

        ;释放对象
        _GDIPlus_GraphicsDispose($hGraphic)

        _GDIPlus_Shutdown()
EndFunc   ;==>GDIPlusDraw

Func GDIPlusDraw2()
        _GDIPlus_Startup()
        Local $hBitmap = _WinAPI_CreateBitmap(400, 200, 1, 32);建立背景位图
        Local $hCDC = _WinAPI_CreateCompatibleDC(0);建立绘图DC
        Local $hOld = _WinAPI_SelectObject($hCDC, $hBitmap);调入图片到DC
        Local $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hCDC);从DC创建图形对象
        _GDIPlus_GraphicsClear($hGraphic, 0xFFCCCCCC);清空图形
        ;设置平滑
        _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
        _GDIPlus_GraphicsSetInterpolationMode($hGraphic, 7)
        
        ;drawstring方式写字
;~         _GDIPlus_GraphicsDrawString($hGraphic, '黑体', 10, 10,'黑体');一时没弄清,这怎么不能出效果了
        $hBrush = _GDIPlus_BrushCreateSolid(0xFF9100CD)
        $hFormat = _GDIPlus_StringFormatCreate()
        $hFamily = _GDIPlus_FontFamilyCreate("黑体")
        $hFont = _GDIPlus_FontCreate($hFamily, 24, 0)
        $tLayout = _GDIPlus_RectFCreate(10, 10, 0, 0)
        $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, 'DrawString方式写字符串', $hFont, $tLayout, $hFormat)
        _GDIPlus_GraphicsDrawStringEx($hGraphic, 'DrawString方式写字符串', $hFont, $aInfo[0], $hFormat, $hBrush)
        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        _GDIPlus_BrushDispose($hBrush)

        ;文字转化为路径方式写字
        $hFormat = _GDIPlus_StringFormatCreate()
        _GDIPlus_StringFormatSetAlign($hFormat, 0);0为左对齐
        $hFamily = _GDIPlus_FontFamilyCreate('Arial')
        $tLayout = _GDIPlus_RectFCreate(0, 50, 390, 30)
        $hPath = _GDIPlus_PathCreate()
        _GDIPlus_PathAddString($hPath, 'Path方式写字符串', $tLayout, $hFamily, 1, 38, $hFormat)
        $hBrush = _GDIPlus_LineBrushCreateFromRect($tLayout, 0xFF02B9EE, 0xFF004696, 1, 3)
        $hPen = _GDIPlus_PenCreate(0xFF263E57, 2, 0)
        _GDIPlus_GraphicsFillPath($hGraphic, $hPath, $hBrush)
        _GDIPlus_GraphicsDrawPath($hGraphic, $hPath, $hPen)
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_PathDispose($hPath)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        
        ;绘制椭圆
        $tLayout = _GDIPlus_RectFCreate(10, 100, 290, 84)
        $hBrush = _GDIPlus_LineBrushCreateFromRect($tLayout, 0x0002B9EE, 0xFF004696, 2, 3)
        $hPen = _GDIPlus_PenCreate(0xFFFFDD00, 1, 0)
        _GDIPlus_GraphicsDrawEllipse($hGraphic, 10, 100, 290, 84, $hPen)
        _GDIPlus_GraphicsFillEllipse($hGraphic, 10, 100, 290, 84, $hBrush)
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_BrushDispose($hBrush)

        ;释放对象
        _GDIPlus_GraphicsDispose($hGraphic)
        _WinAPI_SelectObject($hCDC, $hOld)
        _WinAPI_DeleteDC($hCDC)
        _GDIPlus_Shutdown()
        
        ;设置hBitmap到pic控件
        $oldObj = _SendMessage($hPic, 0x0172, 0, $hBitmap) ;$STM_SETIMAGE = 0x0172
        _WinAPI_DeleteObject($oldObj)
        Local $hObj = _SendMessage($hPic, 0x0173) ;$STM_GETIMAGE = 0x0173
        If $hObj <> $hBitmap Then
                _WinAPI_DeleteObject($hBitmap)
        EndIf
EndFunc   ;==>GDIPlusDraw2

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 2金钱 +48 贡献 +5 收起 理由
afan + 30
user3000 + 18 + 5 谢谢! 钱不够发了!

查看全部评分

发表于 2012-4-26 22:53:44 | 显示全部楼层
回复 12# seniors
看来是美化 GUI 的高手!试过你的一个脚本,CPU 吃不消。。。
发表于 2012-4-27 03:18:10 | 显示全部楼层
本帖最后由 netegg 于 2012-4-27 05:20 编辑

看msdn,个人感觉,gdi+更像是对象操作(尽管不是,是把一些东西封装了起来的),属性,方法一类的一大堆,gdi是纯粹的api函数操作
发表于 2012-4-27 07:56:02 | 显示全部楼层
回复  seniors
看来是美化 GUI 的高手!试过你的一个脚本,CPU 吃不消。。。
131738 发表于 2012-4-26 22:53

什么CPU啊,我没有什么吃不消的感觉啊

看msdn,个人感觉,gdi+更像是对象操作(尽管不是,是把一些东西封装了起来的),属性,方法一类的一大堆, ...
netegg 发表于 2012-4-27 03:18

简单点讲,
gdi是对DC(设备上下文)操作,用什么对象就先要selectobject,用完释放,另gdi的颜色是BGR,不支持透明度;gdi支持的图像类型有BMP、ICO、CUR,即支持位图。
gdi+是对Graphic(画布)操作,绘制函数有参数(如颜色、画笔、填充画刷等),另gdi+的颜色是ARGB,支持透明度。gdi+支持几乎所有的图像类型。

评分

参与人数 1金钱 +35 贡献 +5 收起 理由
3mile + 35 + 5 学习了

查看全部评分

您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-13 10:16 , Processed in 0.080614 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表