gdi和gdi+的区别?
是不是GDIPlus.au3里面的函数就是gdi的而GDIPlusEx.au3里面的函数就是gdi+的 以前也和你一样想法,其实不是的
GDIPlus.au3和GDIPlusEx.au3里面的函数都是gdi+的
API中的图形操作才是gdi的 回复 2# seniors
原来是这样啊,受教了 回复 2# seniors
没碰过GDI, 本来想看看 gdi和gdi+的区别!
可是, 看完帖子, 还是一头雾水啊! 回复 4# user3000
我回家给大家举个例子 回复 5# seniors
期待中!
解我迷惑将重赏! 回复 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+,用户能够访问多种格式的图片文件,转换文件格式等,还能进行图像重新着色、色彩修正、消除走样等图像处理。 回复 7# happytc
1、不再使用设备环境或句柄
======================
这么一说,那2楼说的就不对了
安这个说法,我原来自绘窗体用的还是gdi啊 学习,虽然没看懂 了解了一点GDI和GDI+的不同 回复 8# kenan
我2 楼没有说错啊 本帖最后由 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, $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, $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 回复 12# seniors
看来是美化 GUI 的高手!试过你的一个脚本,CPU 吃不消。。。 本帖最后由 netegg 于 2012-4-27 05:20 编辑
看msdn,个人感觉,gdi+更像是对象操作(尽管不是,是把一些东西封装了起来的),属性,方法一类的一大堆,gdi是纯粹的api函数操作 回复seniors
看来是美化 GUI 的高手!试过你的一个脚本,CPU 吃不消。。。
131738 发表于 2012-4-26 22:53 http://www.autoitx.com/images/common/back.gif
什么CPU啊,我没有什么吃不消的感觉啊
看msdn,个人感觉,gdi+更像是对象操作(尽管不是,是把一些东西封装了起来的),属性,方法一类的一大堆, ...
netegg 发表于 2012-4-27 03:18 http://www.autoitx.com/images/common/back.gif
简单点讲,
gdi是对DC(设备上下文)操作,用什么对象就先要selectobject,用完释放,另gdi的颜色是BGR,不支持透明度;gdi支持的图像类型有BMP、ICO、CUR,即支持位图。
gdi+是对Graphic(画布)操作,绘制函数有参数(如颜色、画笔、填充画刷等),另gdi+的颜色是ARGB,支持透明度。gdi+支持几乎所有的图像类型。
页:
[1]
2