Malkey Posted October 17, 2008 Posted October 17, 2008 (edited) A utility for getting the points array of a bezier curve (spline) for use elsewhere. About Bezier Curve The two end points ( start and last point) have ony one control point. The intermediate points on the bezier curve have two control points. The control points have a thin red line to the curve point they control. Each control point of a curve point governs the entry an exit shape of the curve at that curve point. The angle to, and distance away from the curve point determines the shape of the curve before and after that point on the bezier curve. User Guide A single click and drag on a red spot that does not turn green, drags the desktop size, invisible, layered GUI. A double click and drag on a red spot that does turn green, allows repositioning of that spot (point). And the bezier curve moves in response. Once a point turns green, a single click on another red point is all that is needed the turn other points green for repositioning. When the point turns green and the left mouse button is held down, the tooltip appears showing the point number in the array of points, and the x and y coordinate values. Context Menu Right mouse button click on a point or on the curve brings up a context menu containing:- Toggle hide/show points Add a point - Actually adds three points, a curve point and two control points. Delete a point - Actually deletes three points. Write points array to text file, PolyDat.txt in same directory as script. Notepad.exe is used for display of data. Set space size around bezier points. - Should a point be dragged off layered GUI, entering a space value around all the points will reposition all the points on the layered gui with the space specified. When the bezier curve is how you want it, you can set the space boundary size to zero. Then when you write points to text file, the recommended size width x height, is the minimun size rectangle that will contain all the points. Exit - To exit expandcollapse popup#include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <GuiSlider.au3> #include <Date.au3> #include <WindowsConstants.au3> #include <misc.au3> #include <GuiMenu.au3> #include <WinAPI.au3> Global Const $iOpacity = 255 Global $hGui, $hGraphic, $hBitmap, $hBrush, $hBrush, $SBoth, $GrnPt, $hBrushGrad, $pt = 0 Global $iMinBorder = 25, $bStatFlag = False Global $dll = DllOpen("user32.dll") Global $GuiSizeX = @DesktopWidth, $GuiSizeY = @DesktopHeight ; 200 ; ;Global Const $WM_LBUTTONDOWN = 0x0201 ; Drag Window 1 of 3 addin Global $msg, $exit, $moveAll, $viewpoints, $pointsVisible = 1 Global Const $SS_CENTER = 1 Global $aPoints Opt("MouseCoordMode", 0) Opt("GUIOnEventMode", 1) Opt("WinTitleMatchMode", 2) Local $aPointsJigSaw[38][2] = [[37, 0],[45, 134],[85, 142],[94, 148],[91, 127],[81, 98],[128, 100], _ [112, 130],[105, 143],[123, 153],[161, 138],[173, 220],[154, 177],[147, 183], _ [121, 184],[132, 215],[148, 205],[179, 194],[162, 233],[157, 256],[137, 253], _ [114, 240],[111, 268],[131, 291],[80, 292],[97, 268],[103, 250],[85, 254], _ [44, 257],[41, 237],[25, 204],[62, 218],[80, 218],[79, 186],[59, 194], _ [29, 211],[38, 173],[45, 134]] Local $aPoints26A[26][2] = [[25, 0],[215, 117],[289, 54],[269, 136],[355, 118],[306, 184],[394, 197], _ [309, 225],[385, 274],[287, 270],[313, 346],[227, 288],[198, 366],[163, 284], _ [88, 333],[122, 259],[35, 280],[109, 221],[25, 201],[108, 180],[41, 130], _ [127, 138],[96, 64],[162, 121],[187, 42],[215, 117]] Local $aPoints19A[20][2] = [[19, 0],[348, 25],[348, 94],[206, 94],[281, 198],[344, 198],[344, 250], _ [198, 250],[198, 198],[255, 198],[172, 94],[114, 177],[145, 177],[145, 229], _ [36, 229],[36, 177],[89, 177],[145, 94],[25, 94],[25, 25]] Local $aPoints10A[11][2] = [[10, 0],[618, 105],[278, 131],[334, 187],[801, 411],[52, 377],[604, 165], _ [123, 240],[101, 137],[483, 521],[185, 97]] Local $aPoints10B[11][2] = [[10, 0],[367, 53],[590, 152],[881, 185],[788, 418],[902, 667],[569, 674], _ [308, 847],[253, 547],[56, 377],[287, 248]] BezierCurve($aPointsJigSaw) ; <============= Start ================== Func BezierCurve($aPoints1) Local $0nPoint, $mouseDiffX, $mouseDiffY, $MouseStartPos, $pos $aPoints = $aPoints1 $hGui = GUICreate("GDI+", $GuiSizeX, $GuiSizeY, -1, -1, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUIRegisterMsg($WM_LBUTTONDOWN, "_WinMove") ; Drag Window 2 of 3 addin $ContextMenu = GUICtrlCreateContextMenu() $viewpoints = GUICtrlCreateMenuItem("Show points", $ContextMenu, 1) GUICtrlSetState($viewpoints, $GUI_CHECKED) GUICtrlSetOnEvent($viewpoints, "ShowaPoints") $addpoint = GUICtrlCreateMenuItem("Add a point numbered after selected point number", $ContextMenu) GUICtrlSetOnEvent($addpoint, "AddPoint") $substractpoint = GUICtrlCreateMenuItem("Delete the selected (green) point ", $ContextMenu) GUICtrlSetOnEvent($substractpoint, "SubstractPoint") $separator1 = GUICtrlCreateMenuItem("", $ContextMenu) ; create a separator line $Currentpoints = GUICtrlCreateMenuItem("Write points to 'PolyDat.txt' file", $ContextMenu) GUICtrlSetOnEvent($Currentpoints, "CurrentPoints2Console") $Border = GUICtrlCreateMenuItem("Set Space Size around Bezier Points", $ContextMenu) GUICtrlSetOnEvent($Border, "Border") $separator1 = GUICtrlCreateMenuItem("", $ContextMenu) ; create a separator line $MenuItemExit = GUICtrlCreateMenuItem("Exit", $ContextMenu) GUICtrlSetOnEvent($MenuItemExit, "quitclk") GUISetState() Draw(-1) Do $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Or $exit = 1 Then ExitLoop If _IsPressed("01", $dll) Then ; Virtual-Key Code (0x01) Left mouse button $MouseStartPos = MouseGetPos() $0nPoint = CheckOverPoint($MouseStartPos[0], $MouseStartPos[1]) $mouseDiffX = 0 If $0nPoint > 0 Then ToolTip(TooltipFunc($0nPoint), _ClientToScreen($hGui, $aPoints, $0nPoint, 0) - 30, _ _ClientToScreen($hGui, $aPoints, $0nPoint, 1) + 20) $moveAll = 1 Draw($0nPoint) $GrnPt = $0nPoint While _IsPressed("01", $dll) ; Virtual-Key Code (0x01) Left mouse button $pos = MouseGetPos() $mouseDiffX = Int(($pos[0] - $MouseStartPos[0])) $mouseDiffY = Int(($pos[1] - $MouseStartPos[1])) If Abs($mouseDiffX) > 0 Or Abs($mouseDiffY) > 0 Then $aPoints[$0nPoint][0] = $pos[0] $aPoints[$0nPoint][1] = $pos[1] Draw($0nPoint) ToolTip(TooltipFunc($0nPoint), _ClientToScreen($hGui, $aPoints, $0nPoint, 0) - 30, _ _ClientToScreen($hGui, $aPoints, $0nPoint, 1) + 20) Sleep(200) EndIf Sleep(20) WEnd ToolTip("") Else $moveAll = 0 Draw(-1) EndIf EndIf ; mouse BTN 1 pressed?? Sleep(20) Until _IsPressed("1B") ; ESC key DllClose($dll) EndFunc ;==>BezierCurve ;Check if mouse pointer is over a red/green spot Func CheckOverPoint($MouseX, $MouseY) Local $x, $retValue = -1 For $x = 0 To UBound($aPoints) - 1 If $MouseX < $aPoints[$x][0] + 5 And $MouseX > $aPoints[$x][0] - 5 And _ $MouseY < $aPoints[$x][1] + 5 And $MouseY > $aPoints[$x][1] - 5 Then $retValue = $x EndIf Next Return $retValue EndFunc ;==>CheckOverPoint Func TooltipFunc($0nPoint) Local $sText $sText = "Point: " & $0nPoint & @CRLF & " X: " & $aPoints[$0nPoint][0] & _ " Y: " & $aPoints[$0nPoint][1] & @CRLF Return $sText EndFunc ;==>TooltipFunc Func Draw($pt) Local $hWnd, $hDC, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend, $hBrushRed, $hBrushGreen, $hPen, $aCentPt $GrnPt = $pt _GDIPlus_Startup() $hWnd = _WinAPI_GetDC(0) $hDC = _WinAPI_CreateCompatibleDC($hWnd) $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSizeX, $GuiSizeY) _WinAPI_SelectObject($hDC, $hBitmap) $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) $hPen = _GDIPlus_PenCreate(0xFF010101, 2) $hPenRed = _GDIPlus_PenCreate(0xFFFF0000, 1) $hBrushRed = _GDIPlus_BrushCreateSolid(0x8fff0000) ;red $hBrushGreen = _GDIPlus_BrushCreateSolid(0x8f00ff00) ;Green _GDIPlus_GraphicsClear($hGraphic) _GDIPlus_GraphicsDrawBeziers($hGraphic, $aPoints, $hPen) If $pointsVisible = 1 Then For $x = 1 To UBound($aPoints) - 1 If $x = $pt Then _GDIPlus_GraphicsFillEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10, $hBrushGreen) Else _GDIPlus_GraphicsFillEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10, $hBrushRed) EndIf _GDIPlus_GraphicsDrawEllipse($hGraphic, $aPoints[$x][0] - 5, $aPoints[$x][1] - 5, 10, 10) If Mod($x - 1, 3) = 0 And $x > 3 And $x < UBound($aPoints) - 3 Then _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[$x][0], $aPoints[$x][1], $aPoints[$x + 1][0], $aPoints[$x + 1][1], $hPenRed) _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[$x][0], $aPoints[$x][1], $aPoints[$x - 1][0], $aPoints[$x - 1][1], $hPenRed) EndIf Next _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[1][0], $aPoints[1][1], $aPoints[2][0], $aPoints[2][1], $hPenRed) _GDIPlus_GraphicsDrawLine($hGraphic, $aPoints[UBound($aPoints) - 1][0], $aPoints[UBound($aPoints) - 1][1], _ $aPoints[UBound($aPoints) - 2][0], $aPoints[UBound($aPoints) - 2][1], $hPenRed) EndIf $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", $GuiSizeX) DllStructSetData($tSize, "Y", $GuiSizeY) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGui, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPenRed) ; _GDIPlus_BrushDispose($hBrushGrad[2]) _GDIPlus_BrushDispose($hBrushRed) _GDIPlus_BrushDispose($hBrushGreen) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() _WinAPI_ReleaseDC(0, $hWnd) _WinAPI_DeleteDC($hDC) Return EndFunc ;==>Draw ;Called from context menu check / uncheck Show Points Func ShowaPoints() If $pointsVisible = 1 Then GUICtrlSetState($viewpoints, $GUI_UNCHECKED) $pointsVisible = 0 Else GUICtrlSetState($viewpoints, $GUI_CHECKED) $pointsVisible = 1 EndIf Draw(-1) Return EndFunc ;==>ShowaPoints ;Called from context menu Write Current points to console Func CurrentPoints2Console() If WinExists("PolyDat.txt") Then WinActivate("PolyDat.txt") WinWaitActive("PolyDat.txt") Send("^s") WinWaitActive("PolyDat.txt") Send("{ALT}") Send("f") Send("x") EndIf $hFile = FileOpen("PolyDat.txt", 1) $aPoints[0][0] = UBound($aPoints) - 1 $aPoints[0][1] = 0 $FromStats = SizeStats() $text = "Local $aPoints[" & UBound($aPoints) & "][2] = [[" & $aPoints[0][0] & "," & $aPoints[0][1] & "]," For $x = 1 To UBound($aPoints) - 1 If Mod($x, 7) = 0 Then $text &= " _" & @CRLF & " " $text &= "[" & $aPoints[$x][0] & "," & $aPoints[$x][1] & "]," Next $text = StringTrimRight($text, 1) & "]" FileWriteLine($hFile, "; =========== " & _Now() & " ===================" & @CRLF & @CRLF) FileWriteLine($hFile, $text & @CRLF & @CRLF) FileWriteLine($hFile, "Recommended GUI size : Width X Height = " & $FromStats[4] & " X " & $FromStats[5] & @CRLF & _ "About the points in array: MiniX, MiniY = " & $FromStats[0] & ", " & $FromStats[1] & _ " MaxX, MaxY = " & $FromStats[2] & ", " & $FromStats[3] & _ " Border set to " & $iMinBorder & @CRLF & @CRLF) FileClose($hFile) Run("Notepad.exe PolyDat.txt") Return EndFunc ;==>CurrentPoints2Console ; Called from context menu Exit script. Func quitclk() $exit = 1 ; Chr(27) ; EndFunc ;==>quitclk ; Returns a suitable Width and Height to encompass polygon for use in ; save as image and write to console. Max & Min points are just for info. Func SizeStats() Local $iMinX = $aPoints[1][0], $iMaxX = $aPoints[1][0], $x = 0, $y = 0 Local $iMinY = $aPoints[1][1], $iMaxY = $aPoints[1][1] Local $iMinWidth, $iMinHeigth For $r = 1 To UBound($aPoints) - 1 If $aPoints[$r][0] < $iMinX Then $iMinX = $aPoints[$r][0] If $aPoints[$r][1] < $iMinY Then $iMinY = $aPoints[$r][1] If $aPoints[$r][0] > $iMaxX Then $iMaxX = $aPoints[$r][0] If $aPoints[$r][1] > $iMaxY Then $iMaxY = $aPoints[$r][1] Next Local $iMaxBorder = 80 If Not $bStatFlag Then If $iMinX < $iMinBorder Then $x = $iMinBorder - $iMinX If $iMinY < $iMinBorder Then $y = $iMinBorder - $iMinY If ($iMinX - $iMinBorder) > $iMaxBorder Then $x = $x - ($iMinX - $iMinBorder) If ($iMinY - $iMinBorder) > $iMaxBorder Then $y = $y - ($iMinY - $iMinBorder) If $x <> 0 Or $y <> 0 Then $aPoints = arrayplusScalarPoint($aPoints, $x, $y); If $iMinBorder = 0 Then $aPoints = arrayplusScalarPoint($aPoints, -$iMinX, 0); $bStatFlag = True SizeStats() EndIf $bStatFlag = False $iMinWidth = $iMinX + $iMaxX ; = (2 * $iMinX) + actual width $iMinHeigth = $iMinY + $iMaxY ; = (2 * $iMinY) + actual height Local $aStats[6] = [$iMinX, $iMinY, $iMaxX, $iMaxY, $iMinWidth, $iMinHeigth] Draw(-1) Return $aStats EndFunc ;==>SizeStats ;Called from context menu. Adds a points. eg. if point3 is selected (green) then a new point 4 is added Func AddPoint() ;Local $LastColor If $GrnPt <> Mod($GrnPt - 1, 3) And $GrnPt < 3 And $GrnPt > UBound($aPoints) - 3 Then MsgBox(0, "Add a Point", "Select a point.(NOT Endpoints). (Click on a red point to turn it green)", 0, _ WinGetHandle('Program Manager'));$hGui ); Else Dim $aRET[UBound($aPoints) + 3][2] For $r = 1 To UBound($aPoints) - 1 If $r = $GrnPt Then $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] $aRET[$r + 1][0] = $aPoints[$r][0] + 10 $aRET[$r + 1][1] = $aPoints[$r][1] + 10 $aRET[$r + 2][0] = $aPoints[$r][0] + 20 $aRET[$r + 2][1] = $aPoints[$r][1] + 20 $aRET[$r + 3][0] = $aPoints[$r][0] + 30 $aRET[$r + 3][1] = $aPoints[$r][1] + 30 ElseIf $r > $GrnPt Then $aRET[$r + 3][0] = $aPoints[$r][0] $aRET[$r + 3][1] = $aPoints[$r][1] Else $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] EndIf Next $aPoints = $aRET $aRET = "" Draw(-1) EndIf Return EndFunc ;==>AddPoint ; Called from context menu. Deletes the selected (green) point. Func SubstractPoint() If $GrnPt <> Mod($GrnPt - 1, 3) And $GrnPt < 3 And $GrnPt > UBound($aPoints) - 3 Then MsgBox(0, "Substract a point", "Select a point. (Click on a red point to turn it green", 0, $hGui) Else Dim $aRET[UBound($aPoints) - 3][2] For $r = 1 To UBound($aRET) - 1 If $r >= $GrnPt - 1 Then $aRET[$r][0] = $aPoints[$r + 2][0] $aRET[$r][1] = $aPoints[$r + 2][1] Else $aRET[$r][0] = $aPoints[$r][0] $aRET[$r][1] = $aPoints[$r][1] EndIf Next $aPoints = $aRET $aRET = "" Draw(-1) EndIf Return EndFunc ;==>SubstractPoint Func Border() Local $x = 0, $y = 0 $Bdr = InputBox("Change border space size around the image to be saved", _ "Current border size is " & $iMinBorder & @CRLF & @CRLF & _ "Enter new border size, or Cancel" & @CRLF & @CRLF, $iMinBorder, "", 400, 150, -1, -1, -1, $hGui) If Not @error And Number($Bdr) >= 0 Then $iMinBorder = Number($Bdr) ; Min border size = 1 SizeStats() Draw(-1) Return EndFunc ;==>Border ;Matrix $a plus a Scalar (number) $k (Used in Margin/border Utility) Func arrayplusScalarPoint(ByRef $pts, $x = 0, $y = 0) Dim $aRET[UBound($pts)][2] For $r = 0 To UBound($pts) - 1 $aRET[$r][0] = $pts[$r][0] + $x $aRET[$r][1] = $pts[$r][1] + $y Next Return $aRET EndFunc ;==>arrayplusScalarPoint ; ================================================================= ; Drag Window 3 of 3 addin ; ================================================================= Func _WinMove($hWnd, $Command, $wParam, $lParam) If BitAND(WinGetState($hWnd), 32) Then Return $GUI_RUNDEFMSG If $moveAll = 0 Then DllCall("user32.dll", "int", "SendMessage", "hWnd", $hWnd, "int", $WM_NCLBUTTONDOWN, "int", $HTCAPTION, "int", 0) EndIf Return EndFunc ;==>_WinMove ;_ClientToScreen() Function - Converts client (gui) coordinates to Screen coordinates ;Input - $hwnd - Handle from GUICreate() function ; $cPoint - Array of points in $cPoint[n+1][2] = [[n,0],[x1,y1],[x2,y2],...[xn,yn]] format ; Where n = Number of points ; $index - Index of array e.g for point $cPoint[2][0] and $cPoint[2][1] $index = 2 ; $xy - if 0 then returns screen coordinate of x ; - If 1 then returns screen coordinate of y ; - if 2 then returns array where return array[0] = x, and array[1] = y value Func _ClientToScreen($hWnd, ByRef $cPoint, $index, $xy = 2) Local $tpoint = DllStructCreate("int X;int Y") Local $ret[2] DllStructSetData($tpoint, "X", $cPoint[$index][0]) DllStructSetData($tpoint, "Y", $cPoint[$index][1]) _WinAPI_ClientToScreen($hWnd, $tpoint) $ret[0] = DllStructGetData($tpoint, "X") $ret[1] = DllStructGetData($tpoint, "Y") If $xy = 0 Then Return $ret[0] ; x value If $xy = 1 Then Return $ret[1] ; y value If $xy = 2 Then Return $ret ; array EndFunc ;==>_ClientToScreen ; #FUNCTION# ===================================================================== ; Name...........: _GDIPlus_GraphicsDrawBeziers ========================================== #cs ; Parameters ....: ;$hGraphics Handle to a Graphics object ;$aPoints - An array of points $aPoints[0][0] Total number of points (3*n - 2), where n is number of points on curve $aPoints[0][1] Y coordinate of the 1st (starting) point $aPoints[1][0] X coordinate of the 1st (starting) point $aPoints[1][1] Y coordinate of the 1st (starting) point $aPoints[2][0] X coordinate of the control point for 1st (starting) point $aPoints[2][1] Y coordinate of the first control for 1st (starting) point $aPoints[3][0] X coordinate of the first control point for 2nd point $aPoints[3][1] Y coordinate of the first control point for 2nd point $aPoints[4][0] X coordinate of the 2nd point $aPoints[4][1] Y coordinate of the 2nd point $aPoints[5][0] X coordinate of the second control point for 2nd point $aPoints[5][1] Y coordinate of the second control point for 2nd point $aPoints[n][0] X coordinate of the first control point for nth point $aPoints[n][1] Y coordinate of the first control point for nth point $aPoints[n+1][0] X coordinate of the nth point $aPoints[n+1][1] Y coordinate of the nth point $aPoints[n+2][0] X coordinate of the second control point for nth point $aPoints[n+2][1] Y coordinate of the second control point for nth point $aPoints[Second Last point][0] X coordinate of the first control point for last point $aPoints[Second Last point][1] Y coordinate of the first control point for last point. $aPoints[Last point][0] X coordinate of the ending point $aPoints[Last point][1] Y coordinate of the ending point $hPen Handle to a pen object that is used to draw the bezier. If 0, a solid black pen with a width of 1 will be used. GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points, INT count) #ce Func _GDIPlus_GraphicsDrawBeziers($hGraphics, $aPoints, $hPen = 0) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 ; Modified was $iCount = $aPoints[0][0] $tPoints = DllStructCreate("int[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next ;_GDIPlus_PenDefCreate($hPen) $aResult = DllCall($ghGDIPDll, "int", "GdipDrawBeziersI", "hwnd", $hGraphics, "hwnd", $hPen, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended _GDIPlus_PenDispose($hPen) If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_GDIPlus_GraphicsDrawBeziers Enjoy. Edit: Updated to run on AutoIt version 3.3.6.1 (on 31/10/2010). Edited October 31, 2010 by Malkey wakillon 1
Malkey Posted October 17, 2008 Author Posted October 17, 2008 (edited) This shows the creation and use of a two coloured gradient path brush. The path used is a bezier curve. One colour is the centre colour. The other colour is the boundary or surround colour. expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) ; Creating a Path Gradient @ http://msdn.microsoft.com/en-us/library/ms533917(VS.85).aspx Global $aPoints[11][2] = [[10, 0],[123, 77],[199, 25],[593, 143],[624, 251],[652, 343],[250, 429], _ [171, 403],[78, 381],[25, 125],[123, 77]] Local $hPath, $hGui, $Exit, $hGraphicGUI, $hBMPBuff, $hGraphic, $hPen, $hBrushGrad, $hBitmap = "" Global $GuiSizeX = 680, $GuiSizeY = 480 $hGui = GUICreate("Paths", $GuiSizeX, $GuiSizeY) GUISetOnEvent($GUI_EVENT_CLOSE, "close") $Exit = GUICtrlCreateButton("Exit", 10, 20, 40, 30, -1, $WS_EX_TOPMOST) GUICtrlSetBkColor($Exit, 0x8080f0) GUICtrlSetOnEvent($Exit, "close") GUISetState() _GDIPlus_Startup() ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ;End Double Buffer add-in 1 of 3 $hPath = GDIPlus_CreatePath() _GDIPlus_AddPathBeziers($hPath, $aPoints) $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) $hBrushGrad = GDIPlus_CreatePathGradientBrushFromPath($hPath);,0xFFFFA0A0, 0xFFA0A0FF,True) ; Gamma correction on ;$hBrushGrad = GDIPlus_CreatePathGradientBrushFromPath($hPath,"","",false) ; Gamma correction off _GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFB0) _GDIPlus_GraphicsDrawBeziers($hGraphic, $aPoints, $hPen) ; Draws bezier outline ;GDIPlus_DrawPath($hGraphic, $hPen, $hPath) ; Draws path outline, same result as above. GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath) ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize._GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN ;End Double Buffer add-in 2 of 3 ;$hBitmap = ImageMakeTransparentBkGnd($hBMPBuff, 0, 0, $GuiSizeX, $GuiSizeY) ;_GDIPlus_ImageSaveToFile($hBitmap, @DesktopDir & "\TestWrite1.png") ;ShellExecute(@DesktopDir & "\TestWrite1.png") While 1 Sleep(10) WEnd ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT Func close() _GDIPlus_BrushDispose($hBrushGrad) _GDIPlus_PenDispose($hPen) GDIPlus_DeletePath($hPath) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) If $hBitmap <> "" Then _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() Exit EndFunc ;==>close Func GDIPlus_ClosePathFigure($hPath) Local $aResult1 = DllCall($ghGDIPDll, "int", "GdipClosePathFigure", "hwnd", $hPath) Return EndFunc ;==>GDIPlus_ClosePathFigure ;======== GDIPlus_CreatePath ===== ; $aResult = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", $FillModeAlternate, "ptr", $pPath) ; $FillModeAlternate = 0 ; $FillModeWinding = 1 Func GDIPlus_CreatePath() Local $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", 0, "int*", 0) Return $hPath[2] EndFunc ;==>GDIPlus_CreatePath Func GDIPlus_DeletePath($hPath) DllCall($ghGDIPDll, "int", "GdipDeletePath", "hwnd", $hPath) Return EndFunc ;==>GDIPlus_DeletePath ; Two colours used. $iARGBCentre - A centre color. $pArgbSurround - A boundary color. Func GDIPlus_CreatePathGradientBrushFromPath($hPath, $iARGBCentre = 0xFFFFFFFF, $pArgbSurround = 0xFF000000, $useGammaCorrection = True) Local $hBrush, $tArgb, $pArgb, $result If $iARGBCentre = "" Then $iARGBCentre = 0xFFFFFFFF If $pArgbSurround = "" Then $pArgbSurround = 0xFF000000 $hBrush = DllCall($ghGDIPDll, "int", "GdipCreatePathGradientFromPath", "hwnd", $hPath, "int*", 0) $hBrush = $hBrush[2] $result = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection) $result = DllCall($ghGDIPDll, "int", "GdipSetPathGradientCenterColor", "hwnd", $hBrush, "int", $iARGBCentre) $tArgb = DllStructCreate("int") $pArgb = DllStructGetPtr($tArgb) $result = DllStructSetData($tArgb, 1, $pArgbSurround, 1) $result = DllCall($ghGDIPDll, "int", "GdipSetPathGradientSurroundColorsWithCount", "hwnd", $hBrush, "int", $pArgb, "int*", 1) Return $hBrush EndFunc ;==>GDIPlus_CreatePathGradientBrushFromPath ;========= GDIPlus_DrawPath ========= Func GDIPlus_DrawPath($hGraphic, $hPen, $hPath) Local $aResult2 = DllCall($ghGDIPDll, "int", "GdipDrawPath", "hwnd", $hGraphic, "hwnd", $hPen, "hwnd", $hPath) Return EndFunc ;==>GDIPlus_DrawPath ;======= Fill Path - Color path object == ;GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path) Func GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath) DllCall($ghGDIPDll, "int", "GdipFillPath", "hwnd", $hGraphic, "hwnd", $hBrushGrad, "hwnd", $hPath) Return EndFunc ;==>GDIPlus_FillPath Func ImageMakeTransparentBkGnd($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iColor = Default) Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB) If $iColor = Default Then $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1) ; Transparent color ProgressOn("Making a color Transparent", "The image is being processed.", "0 percent", -1, -1, 16) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") For $i = 0 To $GuiSizeX - 1 For $j = 0 To $GuiSizeY - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $v_Value = DllStructGetData($v_Buffer, 1) If Hex($v_Value, 6) = Hex($iColor, 6) Then DllStructSetData($v_Buffer, 1, Hex($iColor, 6)) ; Sets Transparency here. Alpha Channel = 00, not written to. EndIf Next ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent") Next _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ProgressOff() Return $hBitmap1 EndFunc ;==>ImageMakeTransparentBkGnd ;The GetPixel method gets the color of a specified pixel in this bitmap. Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY) Local $tArgb, $pArgb, $aRet $tArgb = DllStructCreate("dword Argb") $pArgb = DllStructGetPtr($tArgb) $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb) Return "0x" & Hex(DllStructGetData($tArgb, "Argb")) EndFunc ;==>GDIPlus_BitmapGetPixel Func _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, $iARGB) Local $aRet $aRet = DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "dword", $iARGB) Return EndFunc ;==>_GDIPlus_BitmapSetPixel Func GDIPlus_AntiAlias($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_AntiAlias Func GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection) Return $aResult[0] EndFunc ;==>GDIPlus_SetLineGammaCorrection Func _GDIPlus_GraphicsDrawBeziers($hGraphics, $aPoints, $hPen = 0) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 ; or $iCount = $aPoints[0][0] $tPoints = DllStructCreate("int[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next ;_GDIPlus_PenDefCreate($hPen) $aResult = DllCall($ghGDIPDll, "int", "GdipDrawBeziersI", "hwnd", $hGraphics, "hwnd", $hPen, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended ;_GDIPlus_PenDispose() If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_GDIPlus_GraphicsDrawBeziers ;GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) Func _GDIPlus_AddPathBeziers($hPath, $aPoints) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 $tPoints = DllStructCreate("float[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathBeziers", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[2], 0, $aResult[1]) EndFunc ;==>_GDIPlus_AddPathBeziers Edit: Updated to run on AutoIt version 3.3.6.1 (on 31/10/2010). Edited October 31, 2010 by Malkey
Malkey Posted October 17, 2008 Author Posted October 17, 2008 (edited) This example is of a multi-coloured, gradient filled, bezier path.It uses all the points of the bezier array of points, (curve, control , and end points ), to locate the boundary (surround) colours. The points act as a polygon and at each point of the polygon is a colour which blends with the centre colour and the two adjoining colours at the points before and after along the polygon boundary.This only works because all the points in the array lie on, or outside the bezier curve. When the gradient brush is created from the bezier curve path, there are no missing bits of colour where the polygon might cross over to the inside of the path. There would be no colour from the outside of the polygon to the inside of the bezier curved path when filled with the gradient brush. I haven't tried this yet. Compile the first post (Bezier Utility) and/or compile the script at http://www.autoitscript.com/forum/index.ph...st&p=552977 With this script you can create a coloured polygon. The Bezier Utility is a stripped down modified version of this coloured polygon script.With both scripts running, it should be possible to manipulate the surrounding polyon, the colours at each point of the polygon, the centre point colour, and the shape of the bezier curve and position.Both scripts write its data to a PolyDat.txt file. From the coloured polygon script you get the points and colours arrays, and centre colour, for the _GDIPlus_CreateBezierGradientBrush() function in the script at this post before the loop.From Bezier Utility you get the array of points for _GDIPlus_AddPathBeziers($hPath, $aPoints) in the loop.So what you saw inside the bezier curve should be what is displayed with this script, when the data from PolyDat.txt is added.expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> HotKeySet("{ESC}", "close") ; Creating a Path Gradient @ http://msdn.microsoft.com/en-us/library/ms533917(VS.85).aspx Global $aPoints[11][2] = [[10, 0],[123, 77],[199, 25],[593, 143],[624, 251],[652, 343],[250, 429], _ [171, 403],[78, 381],[25, 125],[123, 77]] Global $aColors[10] = [0xFF0000FF, 0xFFFF0000, 0xFF0000FF, 0xFFFFFF00, 0xFF00FF00, _ 0xFF0000FF, 0xFFFF0000, 0xFF0000FF, 0xFFFFFF00, 0xFF00FF00] Global $GuiSizeX = 680, $GuiSizeY = 480 Local $hPath, $hBrushGrad[10], $aColorB $hGui = GUICreate("Paths", $GuiSizeX, $GuiSizeY) _GDIPlus_Startup() ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ;End Double Buffer add-in 1 of 3 _GDIPlus_GraphicsClear($hGraphic, 0xfFfffff0) ;Create array of different gradient brushes by rotating values in $aColors array. $aColorB = $aColors For $n = 0 To UBound($aColors) - 1 For $m = 0 To UBound($aColors) - 1 ; Rotate values in $aColors array. $aColorB[Mod($m + $n, UBound($aColors))] = $aColors[$m] Next $aColorB[0] = $aColorB[UBound($aColorB) - 1] $hBrushGrad[$n] = _GDIPlus_CreateBezierGradientBrush($hBMPBuff, $hGraphic, 0xFFFFB0B0, $aColorB, $aPoints, False, 1.0) _GDIPlus_GraphicsClear($hGraphic, 0xfFfffff0); Always start with a clean buffer! Next ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize. ;End Double Buffer add-in 2 of 3 GUISetState() Local $m = 0 While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE close() EndSwitch $n = Mod($n + 1, UBound($aColors)) ; $hBrushGrad index number $hPath = GDIPlus_CreatePath() _GDIPlus_AddPathBeziers($hPath, $aPoints) GDIPlus_ClosePathFigure($hPath) GDIPlus_FillPath($hGraphic, $hBrushGrad[$n], $hPath) GDIPlus_DeletePath($hPath) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ; Increase & decrease sleep lenght time. If $m = 0 Then $p = 1 If $m = 101 Then $p = -1 $m += $p Sleep(50 + 2 * $m) WEnd ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT Func close() For $n = 0 To UBound($hBrushGrad) - 1 _GDIPlus_BrushDispose($hBrushGrad[$n]) Next ;_GDIPlus_PenDispose($hPen) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() Exit EndFunc ;==>close ;Use bezier $aPoints here only when all path and control points lie outside or on bezier path. ; Otherwise, $aPoints should be points of a polygon which lies outside or on bezier path. These ; polygon points should have corresponding color values in the $aColors array. Func _GDIPlus_CreateBezierGradientBrush($hBMPBuff, $hGraphic, $iColorCentre, $aColors, $aPoints, _ $bGammaCorrection = True, $iTransparency = 1.0) Local $hBrushGrad, $hPath, $status, $hImage, $oImage $hPath = GDIPlus_CreatePath() GDIPlus_AddPathLine2($hPath, $aPoints) $hBrushGrad = GDIPlus_CreatePathGradientFromPath($hPath) GDIPlus_SetLineGammaCorrection($hBrushGrad, $bGammaCorrection) GDIPlus_SetPathGradientCenterColor($hBrushGrad, $iColorCentre) $status = GDIPlus_SetPathGradientSurroundColorsWithCount($hBrushGrad, $aColors) GDIPlus_ClosePathFigure($hPath) GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath) $hImage = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBMPBuff) $oImage = _GDIPlus_BitmapCreateFromHBITMAP($hImage) _GDIPlus_BrushDispose($hBrushGrad) $hBrushGrad = _GDIPlus_CreateTextureTrans($oImage, 1.0, 0, 0, "", ""); Adds the color to $hBrushGrad brush. GDIPlus_SetLineGammaCorrection($hBrushGrad, $bGammaCorrection) _WinAPI_DeleteObject($hImage) _WinAPI_DeleteObject($oImage) GDIPlus_DeletePath($hPath) Return $hBrushGrad EndFunc ;==>_GDIPlus_CreateBezierGradientBrush ;GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count) Func GDIPlus_AddPathLine2($hPath, $aPoints) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 $tPoints = DllStructCreate("int[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, _WinAPI_FloatToInt($aPoints[$iI][0]), (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, _WinAPI_FloatToInt($aPoints[$iI][1]), (($iI - 1) * 2) + 2) Next $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathLine2", "hwnd", $hPath, "ptr", _ $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended ;_GDIPlus_BrushDispose() If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_AddPathLine2 Func GDIPlus_ClosePathFigure($hPath) Local $aResult1 = DllCall($ghGDIPDll, "int", "GdipClosePathFigure", "hwnd", $hPath) Return EndFunc ;==>GDIPlus_ClosePathFigure Func GDIPlus_AddPathEllipse($hPath, $iX, $iY, $iWidth, $iHeight) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathEllipse", "hwnd", $hPath, "int", _WinAPI_FloatToInt($iX), _ "int", _WinAPI_FloatToInt($iY), "int", _WinAPI_FloatToInt($iWidth), "int", _WinAPI_FloatToInt($iHeight)) EndFunc ;==>GDIPlus_AddPathEllipse ;======== GDIPlus_CreatePath ===== ; $aResult = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", $FillModeAlternate, "ptr", $pPath) ; $FillModeAlternate = 0 ; $FillModeWinding = 1 ; GdipCreatePath(GpFillMode brushMode, GpPath **path) Func GDIPlus_CreatePath() Local $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", 0, "int*", 0) Return $hPath[2] EndFunc ;==>GDIPlus_CreatePath Func GDIPlus_DeletePath($hPath) DllCall($ghGDIPDll, "int", "GdipDeletePath", "hwnd", $hPath) Return EndFunc ;==>GDIPlus_DeletePath ;====== Create Gradient Brush from Path ======= ;GdipCreatePathGradientFromPath(GDIPCONST GpPath* path, GpPathGradient **polyGradient) Func GDIPlus_CreatePathGradientFromPath($hPath) Local $hBrushGrad $hBrushGrad = DllCall($ghGDIPDll, "int", "GdipCreatePathGradientFromPath", "hwnd", $hPath, "int*", 0) Return $hBrushGrad[2] EndFunc ;==>GDIPlus_CreatePathGradientFromPath ;======> End of GDIPlus_CreatePathGradientFromPath ======= Func GDIPlus_CreatePathGradientBrushFromPath($hPath, $iARGBCentre = 0xFFFFFFFF, $pArgbSurround = 0xFF000000, _ $bGammaCorrection = True) Local $hBrush, $tArgb, $pArgb, $result If $iARGBCentre = "" Then $iARGBCentre = 0xFFFFFFFF If $pArgbSurround = "" Then $pArgbSurround = 0xFF000000 ;$pArgbSurround = String($pArgbSurround) $hBrush = DllCall($ghGDIPDll, "int", "GdipCreatePathGradientFromPath", "hwnd", $hPath, "int*", 0) $hBrush = $hBrush[2] $result = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $bGammaCorrection) $result = DllCall($ghGDIPDll, "int", "GdipSetPathGradientCenterColor", "hwnd", $hBrush, "int", $iARGBCentre) $tArgb = DllStructCreate("int") $pArgb = DllStructGetPtr($tArgb) $result = DllStructSetData($tArgb, 1, $pArgbSurround, 1) $result = DllCall($ghGDIPDll, "int", "GdipSetPathGradientSurroundColorsWithCount", "hwnd", $hBrush, _ "int", $pArgb, "int*", 1) Return $hBrush EndFunc ;==>GDIPlus_CreatePathGradientBrushFromPath ;========= GDIPlus_DrawPath ========= Func GDIPlus_DrawPath($hGraphic, $hPen, $hPath) Local $aResult2 $aResult2 = DllCall($ghGDIPDll, "int", "GdipDrawPath", "hwnd", $hGraphic, "hwnd", $hPen, "hwnd", $hPath) Return EndFunc ;==>GDIPlus_DrawPath ;======= Fill Path - Color path object == ;GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path) Func GDIPlus_FillPath($hGraphic, $hBrushGrad, $hPath) DllCall($ghGDIPDll, "int", "GdipFillPath", "hwnd", $hGraphic, "hwnd", $hBrushGrad, "hwnd", $hPath) Return EndFunc ;==>GDIPlus_FillPath ;=======> End of GDIPlus_FillPath ============== ;================> GDIPlus_SetPathGradientCenterColor =============== ; Description Sets the center color of this path gradient brush. The center color is the ; color that appears at the brush's center point. ;Parameters ;brush [in] Pointer to the PathGradientBrush object. ;colors [in] An ARGB color that specifies the center color. ;Remarks By default the center point is the centroid of the brush's boundary path, ; but you can set the center point to any location inside or outside the path. ; Func GDIPlus_SetPathGradientCenterColor($hBrush, $iARGB) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetPathGradientCenterColor", "hwnd", $hBrush, "int", $iARGB) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult);$aResult ; EndFunc ;==>GDIPlus_SetPathGradientCenterColor ;================================================= ;GdipGetPathGradientCenterPoint( GpPathGradient *brush, GpPointF* points) ; Func GDIPlus_GetPathGradientCenterPoint($hBrush) Local $aResult, $res, $iX, $iY, $Pt, $pPt, $aPt[2] $Pt = DllStructCreate("int X;int Y") $pPt = DllStructGetPtr($Pt) $aResult = DllCall($ghGDIPDll, "int", "GdipGetPathGradientCenterPoint", "hwnd", $hBrush, "ptr", $pPt) $iX = Round(_WinAPI_IntToFloat(DllStructGetData($Pt, 'X')), 0) $iY = Round(_WinAPI_IntToFloat(DllStructGetData($Pt, 'Y')), 0) ;$res = "GdipGetPathGradientCenterPoint" & @CRLF $aPt[0] = $iX $aPt[1] = $iY Return $aPt EndFunc ;==>GDIPlus_GetPathGradientCenterPoint ;================================================= ;==============> GDIPlus_SetPathGradientSurroundColorsWithCount =================================== ;Description Sets the surround colors of this path gradient brush. The surround colors are colors ; specified for discrete points on the brush's boundary path. ;Parameters ;brush [in] Pointer to the PathGradientBrush object. ;colors [in] Pointer to an array of ARGB colors that specify the surround colors. ;count [in, out] Pointer to a long integer that, on input, specifies the number of Color objects ; in the colors array. If the method succeeds, this parameter, on output, receives the number ; of surround colors set. If the method fails, this parameter does not receive a value. ;Remarks A path gradient brush has a boundary path and a center point. The center point is set ; to a single color, but you can specify different colors for several points on the boundary. ; For example, suppose you specify red for the center color, and you specify blue, green, ; and yellow for distinct points on the boundary. Then as you move along the boundary, ; the color will change gradually from blue to green to yellow and back to blue. ; As you move along a straight line from any point on the boundary to the center point, ; the color will change from that boundary point's color to red. ; Func GDIPlus_SetPathGradientSurroundColorsWithCount($hBrush, $aArgb) Local $iI, $iCount, $aResult, $res, $x, $tArgb, $pArgb If IsArray($aArgb) Then $iCount = UBound($aArgb) ;_WinAPI_FloatToInt(UBound($aArgb)) ; $tArgb = DllStructCreate("int[" & $iCount & "]") $pArgb = DllStructGetPtr($tArgb) For $iI = 0 To $iCount - 1 DllStructSetData($tArgb, 1, $aArgb[$iI], $iI + 1) Next Else $iCount = 1 $tArgb = DllStructCreate("int") $pArgb = DllStructGetPtr($tArgb) DllStructSetData($tArgb, 1, $aArgb, 1) EndIf $aResult = DllCall($ghGDIPDll, "int", "GdipSetPathGradientSurroundColorsWithCount", "hwnd", $hBrush, _ "int", $pArgb, "int*", $iCount) If @error Then Return SetError(@error, @extended, 0) Return SetError(0, 0, $aResult) ; $aResult ; EndFunc ;==>GDIPlus_SetPathGradientSurroundColorsWithCount ;================================================= ; Gets the number of colors that have been specified for the boundary path of this path gradient brush. ; Func GDIPlus_GetPathGradientSurroundColorCount($hBrush) Local $iCount, $res, $x $iCount = DllCall($ghGDIPDll, "int", "GdipGetPathGradientSurroundColorCount", "hwnd", $hBrush, "int*", 0) Return $iCount[2] EndFunc ;==>GDIPlus_GetPathGradientSurroundColorCount ;GdipGetPathGradientSurroundColorsWithCount( GpPathGradient *brush, ARGB* color, INT* count) Func GDIPlus_GetPathGradientSurroundColorsWithCount($hBrush) Local $iI, $iCount, $aArgb, $tArgb, $pArgb, $aResult, $res, $iCount1 $iCount1 = GDIPlus_GetPathGradientSurroundColorCount($hBrush) Local $aArgb[$iCount1 - 1] $iCount1 = UBound($aArgb) ;_WinAPI_FloatToInt(UBound($aArgb)) ; $tArgb = DllStructCreate("int[" & $iCount & "]") $pArgb = DllStructGetPtr($tArgb) $aResult = DllCall($ghGDIPDll, "int", "GdipGetPathGradientSurroundColorsWithCount", "hwnd", $hBrush, "int*", $pArgb, "int*", $iCount) For $iI = 1 To $iCount1 $aArgb[$iI - 1] = DllStructGetData($tArgb, 1, "") Next If @error Then Return SetError(@error, @extended, 0) Return $aResult ;SetError($aResult[0], 0, $aResult[2]) EndFunc ;==>GDIPlus_GetPathGradientSurroundColorsWithCount Func GDIPlus_AntiAlias($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_AntiAlias Func GDIPlus_SetLineGammaCorrection($hBrush, $bGammaCorrection = True) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $bGammaCorrection) Return $aResult[0] EndFunc ;==>GDIPlus_SetLineGammaCorrection Func _GDIPlus_GraphicsDrawBeziers($hGraphics, $aPoints, $hPen = 0) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 ; or $iCount = $aPoints[0][0] $tPoints = DllStructCreate("int[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next ;_GDIPlus_PenDefCreate($hPen) $aResult = DllCall($ghGDIPDll, "int", "GdipDrawBeziersI", "hwnd", $hGraphics, "hwnd", $hPen, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended ;_GDIPlus_PenDispose() If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_GDIPlus_GraphicsDrawBeziers ;GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) Func _GDIPlus_AddPathBeziers($hPath, $aPoints) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 $tPoints = DllStructCreate("float[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathBeziers", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[2], 0, $aResult[1]) ; $aResult[1] ; EndFunc ;==>_GDIPlus_AddPathBeziers Func GDIPlus_SetClipGraphics($hGraphics, $hsrcgraphics, $combineMode) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetClipGraphics", "hwnd", $hGraphics, "hwnd", $hsrcgraphics, "int", $combineMode) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_SetClipGraphics Func GDIPlus_SetClipPath($hGraphics, $hPath, $combineMode) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetClipPath", "hwnd", $hGraphics, "hwnd", $hPath, "int", $combineMode) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_SetClipPath ; GdipResetClip(GpGraphics *graphics) Func GDIPlus_ResetClip($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipResetClip", "hwnd", $hGraphics) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_ResetClip Func _GDIPlus_CreateTextureTrans($hImage, $nTrans = 0.5, $iX = 0, $iY = 0, $iWidth = "", $iHeight = "") Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) If $iWidth = 0 Or $iWidth = "" Then $iWidth = $iW If $iHeight = 0 Or $iHeight = "" Then $iHeight = $iH ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;blending values: $x = DllStructSetData($tColorMatrix, 1, 1, 1) * DllStructSetData($tColorMatrix, 2, 1, 2) * DllStructSetData($tColorMatrix, 3, 1, 3) * _ DllStructSetData($tColorMatrix, 4, $nTrans, 4) * DllStructSetData($tColorMatrix, 5, 1, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) $hImgAttrib = $hImgAttrib[1] DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, _ "int", 1, "ptr", DllStructGetPtr($tColorMatrix), "ptr", 0, "int", 0) ;;draw image into graphic object with alpha blend Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateTextureIAI", "hwnd", $hImage, "ptr", $hImgAttrib, "int", $iX, "int", _ $iY, "int", $iWidth, "int", $iHeight, "ptr*", 0) ;clean up DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return $aResult[7] EndFunc ;==>_GDIPlus_CreateTextureTransEdit: Updated to run on AutoIt version 3.3.6.1 (on 31/10/2010). Edited October 31, 2010 by Malkey
Malkey Posted October 17, 2008 Author Posted October 17, 2008 This script creates a centre jigsaw piece from a bezier curve and fills that piece with a clipped image. The finished jigsaw piece can be rotated at 90 degree increments. using the middle mouse button or spacebar. Just wanted to see if it could be done completely in AutoIt. What would be really good if a bevelled edge could be added to the jigsaw piece as ImageMagick can do - without using ImageMagick. This script leave an image file, JigSawCentrePiece.png, on the desktop. expandcollapse popup#include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <Misc.au3> #include <WindowsConstants.au3> Global Const $GUI_Width = 400, $GUI_Height = 400 Global $hGui1 $hGui = GUICreate("GDI+", $GUI_Width, $GUI_Height, (@DesktopWidth - $GUI_Width) / 2, 10) GUISetState() ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize. _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@WindowsDir & "\Web\Wallpaper\Ascent.jpg") $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GUI_Width, $GUI_Height, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) _GDIPlus_GraphicsClear($hGraphic, 0xFFF8FFE8) _AntiAlias($hGraphic) _GDIPlus_GraphicsClear($hGraphic, 0xFFF8FFE8) Local $aPoints[38][2] = [[37, 0],[20, 36],[60, 44],[69, 50],[66, 29],[56, 0],[103, 2], _ [87, 32],[80, 45],[98, 55],[136, 40],[148, 122],[129, 79],[122, 85], _ [96, 86],[107, 117],[123, 107],[154, 96],[137, 135],[132, 158],[112, 155], _ [89, 142],[86, 170],[106, 193],[55, 194],[72, 170],[78, 152],[60, 156], _ [19, 159],[16, 139],[0, 106],[37, 120],[55, 120],[54, 88],[34, 96], _ [4, 113],[13, 75],[20, 36]] Local $x = 0, $y = 10 _SetClipBezier($hGraphic, $aPoints, $x, $y) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $GUI_Width, $GUI_Height) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) $hBitmap = ImageColorToTransparent($hBMPBuff, $x, $y, 154, 194);, 0xFFFFFFFF) _GDIPlus_ImageSaveToFile($hBitmap, @DesktopCommonDir & "\JigSawCentrePiece.png") ;ShellExecute(@DesktopCommonDir & "\JigSawCentrePiece.png") GDIPlus_ResetClip($hGraphic) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, $GUI_Width / 2 - 50, $GUI_Height / 2 - 30, $GUI_Width / 2 + 50, $GUI_Height / 2 + 30) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) GUICtrlCreateLabel("Press middle mouse button or spacebar" & @CRLF & _ "to rotate layered GUI ( JigSaw piece )." & @CRLF & " And, it is draggable.", $GUI_Width / 2, 10) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hBitmap) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_ImageDispose($hImage) ;============================================================================== Global Const $iOpacity = 254 ;Global Const $ULW_ALPHA = 2 Global $GuiSize = 200 Global Const $nPI = 3.1415926535897932384626433832795 Global Const $WM_LBUTTONDOWN = 0x0201 ; Drag Window 1 of 3 addin Global $iPath = @DesktopCommonDir & "\JigSawCentrePiece.png" Global $angle ;$nAngle = 0 GUIRegisterMsg($WM_LBUTTONDOWN, "_WinMove") ; Drag Window 2 of 3 addin $hGui1 = GUICreate("GDI+ Rotate", $GuiSize, $GuiSize, @DesktopWidth/2 - 230, 200, 0, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetState() RotatePiece() Do $msg = GUIGetMsg() If _IsPressed("20") Or _IsPressed("04") Then ; SpaceBar or middle mouse button $angle = Mod($angle + 90, 360) ; 10deg increments (plus clockwise) RotatePiece($angle) EndIf Until _IsPressed("1B") Or $msg = -3 ; ESC key ; Clean up resources _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_GraphicsDispose($hGraphicGUI) _GDIPlus_Shutdown() Func RotatePiece($angle = 0) Local $hMatrix, $nX, $nY, $x, $y, $Pos[4], $radius, $hGraphic, $hImage Local $hWnd, $hDC, $hBitmap, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend, $nXt, $nYt $hWnd = _WinAPI_GetDC(0) $hDC = _WinAPI_CreateCompatibleDC($hWnd) $hBitmap = _WinAPI_CreateCompatibleBitmap($hWnd, $GuiSize, $GuiSize) _WinAPI_SelectObject($hDC, $hBitmap) $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) $hImage = _GDIPlus_ImageLoadFromFile($iPath) $Pos = WinGetPos($hGui1) ; "GDI+ Rotate") ConsoleWrite($Pos & @CRLF) $nX = $Pos[0] $nY = $Pos[1] $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixRotate($hMatrix, $angle, False) _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix) $x = ($GuiSize / 2) * Cos($angle * $nPI / 180) - ($GuiSize / 2) + $nX - ($GuiSize / 2) * Sin($angle * $nPI / 180);Parametric equations for a circle $y = ($GuiSize / 2) * Sin($angle * $nPI / 180) - ($GuiSize / 2) + $nY + ($GuiSize / 2) * Cos($angle * $nPI / 180); and adjusts for center of text box $nXt = ($nX - $x) * Cos($angle * $nPI / 180) + ($nY - $y) * Sin($angle * $nPI / 180) $nYt = -($nX - $x) * Sin($angle * $nPI / 180) + ($nY - $y) * Cos($angle * $nPI / 180) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, $nXt + ($GuiSize * 0.2), $nYt + ($GuiSize * 0.2), $GuiSize * 0.6, $GuiSize * 0.6) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", $GuiSize) ;$iWidth ) DllStructSetData($tSize, "Y", $GuiSize) ;$iHeight) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGui1, $hWnd, 0, $pSize, $hDC, $pSource, 0, $pBlend, $ULW_ALPHA) Sleep(500) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_MatrixDispose($hMatrix) _WinAPI_ReleaseDC(0, $hWnd) _WinAPI_DeleteObject($hBitmap) _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteDC($hDC) Return 1 EndFunc ;==>RotatePiece ; ================================================================= ; Drag Window 3 of 3 addin (from AutoIt forum) ; ================================================================= Func _WinMove($hWnd, $Command, $wParam, $lParam) If BitAND(WinGetState($hWnd), 32) Then Return $GUI_RUNDEFMSG DllCall("user32.dll", "int", "SendMessage", "hWnd", $hWnd, "int", $WM_NCLBUTTONDOWN, "int", $HTCAPTION, "int", 0) EndFunc ;==>_WinMove Func _SetClipBezier($hGraphics, $aPoints, $x, $y) Local $aResult, $hPath = GDIPlus_CreatePath() Local $aTempPoints = ArrayPlusScalar($aPoints, $x, $y) _GDIPlus_AddPathBeziers($hPath, $aTempPoints) ;Trace path with pen Local $hPen = _GDIPlus_PenCreate() _GDIPlus_PenDispose($hPen) ;Apply mask $aResult = DllCall($ghGDIPDll, "int", "GdipSetClipPath", "hwnd", $hGraphics, "ptr", $hPath, "int", 1) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_SetClipBezier Func ArrayPlusScalar($pts, $x = 0, $y = 0) Dim $aRET[UBound($pts)][2] For $r = 0 To UBound($pts) - 1 $aRET[$r][0] = $pts[$r][0] + $x $aRET[$r][1] = $pts[$r][1] + $y Next Return $aRET EndFunc ;==>ArrayPlusScalar Func _AntiAlias($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>_AntiAlias Func _GDIPlus_CreateTextureTrans($hImage, $nTrans = 0.5, $iX = 0, $iY = 0, $iWidth = "", $iHeight = "") Local $tColorMatrix, $x, $hImgAttrib, $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) If $iWidth = 0 Or $iWidth = "" Then $iWidth = $iW If $iHeight = 0 Or $iHeight = "" Then $iHeight = $iH ;;create color matrix data $tColorMatrix = DllStructCreate("float[5];float[5];float[5];float[5];float[5]") ;blending values: $x = DllStructSetData($tColorMatrix, 1, 1, 1) * DllStructSetData($tColorMatrix, 2, 1, 2) * DllStructSetData($tColorMatrix, 3, 1, 3) * _ DllStructSetData($tColorMatrix, 4, $nTrans, 4) * DllStructSetData($tColorMatrix, 5, 1, 5) ;;create an image attributes object and update its color matrix $hImgAttrib = DllCall($ghGDIPDll, "int", "GdipCreateImageAttributes", "ptr*", 0) $hImgAttrib = $hImgAttrib[1] DllCall($ghGDIPDll, "int", "GdipSetImageAttributesColorMatrix", "ptr", $hImgAttrib, "int", 1, _ "int", 1, "ptr", DllStructGetPtr($tColorMatrix), "ptr", 0, "int", 0) ;;draw image into graphic object with alpha blend Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateTextureIAI", "hwnd", $hImage, "ptr", $hImgAttrib, "int", $iX, "int", _ $iY, "int", $iWidth, "int", $iHeight, "ptr*", 0) ;clean up DllCall($ghGDIPDll, "int", "GdipDisposeImageAttributes", "ptr", $hImgAttrib) Return $aResult[7] EndFunc ;==>_GDIPlus_CreateTextureTrans Func GDIPlus_CreatePath() Local $hPath, $res $hPath = DllCall($ghGDIPDll, "int", "GdipCreatePath", "int", 0, "int*", 0) Return $hPath[2] EndFunc ;==>GDIPlus_CreatePath ; GdipResetClip(GpGraphics *graphics) Func GDIPlus_ResetClip($hGraphics) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipResetClip", "hwnd", $hGraphics) If @error Then Return SetError(@error, @extended, False) Return SetError($aResult[0], 0, $aResult[0] = 0) EndFunc ;==>GDIPlus_ResetClip ;GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count) Func _GDIPlus_AddPathBeziers($hPath, $aPoints) Local $iI, $iCount, $pPoints, $tPoints, $aResult, $tmpError, $tmpExError $iCount = UBound($aPoints) - 1 $tPoints = DllStructCreate("float[" & $iCount * 2 & "]") $pPoints = DllStructGetPtr($tPoints) For $iI = 1 To $iCount DllStructSetData($tPoints, 1, $aPoints[$iI][0], (($iI - 1) * 2) + 1) DllStructSetData($tPoints, 1, $aPoints[$iI][1], (($iI - 1) * 2) + 2) Next $aResult = DllCall($ghGDIPDll, "int", "GdipAddPathBeziers", "hwnd", $hPath, "ptr", $pPoints, "int", $iCount) $tmpError = @error $tmpExError = @extended If $tmpError Then Return SetError($tmpError, $tmpExError, False) Return SetError($aResult[2], 0, $aResult[1]); $aResult[1] EndFunc ;==>_GDIPlus_AddPathBeziers Func ImageColorToTransparent($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iColor = Default) Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB) If $iColor = Default Then $iColor = GDIPlus_BitmapGetPixel($hBitmap1, 1, 1) ; Transparent color ConsoleWrite($iColor & @CRLF) ProgressOn("Making a color Transparent", "The image is being processed.", "0 percent", -1, -1, 16) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") For $i = 0 To $GuiSizeX - 1 For $j = 0 To $GuiSizeY - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $v_Value = DllStructGetData($v_Buffer, 1) If Hex($v_Value, 6) = Hex($iColor, 6) Then DllStructSetData($v_Buffer, 1, Hex($iColor, 6)) ; Sets Transparency here. Alpha Channel = 00, not written to. EndIf Next ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent") Next _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ProgressOff() Return $hBitmap1 EndFunc ;==>ImageColorToTransparent ;The GetPixel method gets the color of a specified pixel in this bitmap. Func GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY) Local $tArgb, $pArgb, $aRET $tArgb = DllStructCreate("dword Argb") $pArgb = DllStructGetPtr($tArgb) $aRET = DllCall($ghGDIPDll, "int", "GdipBitmapGetPixel", "hwnd", $hBitmap, "int", $iX, "int", $iY, "ptr", $pArgb) Return "0x" & Hex(DllStructGetData($tArgb, "Argb")) EndFunc ;==>GDIPlus_BitmapGetPixel ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) ; Check, if the GUI with the Graphic should be repainted ; The sequencial order of these two commands is important. _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT wakillon 1
Greenhorn Posted October 17, 2008 Posted October 17, 2008 (edited) Yes, I agree with gesller, well done, Malkey ! Greetz Greenhorn Edited October 17, 2008 by Greenhorn
ptrex Posted October 17, 2008 Posted October 17, 2008 @Malkey This is realy the max !! regards, ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
Malkey Posted October 17, 2008 Author Posted October 17, 2008 gesller, Greenhorn, ptrex. Thank-you for your positive response.Further to my comment in post 4, the jigsaw one about a beveled edge without using ImageMagick. I found my AutoIt accessing ImageMagick script that still works.So if you have ImageMagick installed, and,if you have the JigSawCentrePiece.png still on your desktop from the post 4 jigsaw script, and,you do not mind three more image files starting with JigSaw put on your desktop, then try the following script.The first image created has a bevel added.The second adds thickness.The third image has a shadow added. This was the mental picture I had when I made the comment in post 4.This is a link to the ImageMagick site,http://www.imagemagick.org/script/index.phpDim $img Dim $ret ; Initialize error handler $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") $img = ObjCreate("ImageMagickObject.MagickImage.1") $ret = $img.Convert (@DesktopCommonDir & "\JigSawCentrePiece.png", _ "(", "+clone", "-channel", "A", "-separate", "+channel", "-negate", _ "-background", "black", "-virtual-pixel", "background", _ "-blur", "0x2", "-shade", "120x21.78", "-contrast-stretch", "0%", _ "+sigmoidal-contrast", "7x50%", "-fill", "grey50", "-colorize", "10%", _ "+clone", "+swap", "-compose", "overlay", "-composite", ")", _ "-compose", "In", "-composite", @DesktopCommonDir & "\jigsaw_bevel.png") ;ShellExecute(@DesktopCommonDir & "\jigsaw_bevel.png") $ret = $img.Convert (@DesktopCommonDir & "\jigsaw_bevel.png", _ "(", "+clone", "-fill", "DarkSlateGrey", "-colorize", "100%", "-repage", "+0+1", ")", _ "(", "+clone", "-repage", "+1+2 ", ")", "(", "+clone", "-repage", "+1+3", ")", _ "(", "+clone", "-repage", "+2+4", ")", "(", "+clone", "-repage", "+2+5", ")", _ "-background", "none", "-compose", "DstOver", "-flatten", _ @DesktopCommonDir & "\jigsaw_thickness.png") $ret = $img.Convert (@DesktopCommonDir & "\jigsaw_thickness.png", _ "(", "+clone", "-background", "Black", "-shadow", "50x3+4+4", ")", _ "-background", "none", "-compose", "DstOver", "-flatten", _ @DesktopCommonDir & "\jigsaw_shaddow.png") ;ShellExecute(@DesktopCommonDir & "\jigsaw_shaddow.png")For more information about ImageMagick, search the AutoIt forums.
ptrex Posted October 17, 2008 Posted October 17, 2008 @allFor more information about ImageMagick, search the AutoIt forums.Or look here ImageMagick in Au3regards,ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now