UEZ Posted 7 hours ago Posted 7 hours ago (edited) I enhanced the Delaunay function in my _GDIPlus_BitmapApplyFilter Dll and created a front-end GUI to generate Low-Polygon images: Code: expandcollapse popup;Coded by UEZ v0.50 build 2026-02-07 ;Requires 3.3.15.0+ version #AutoIt3Wrapper_Version=p #AutoIt3Wrapper_UseX64=y #include <ComboConstants.au3> #include <EditConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <ScreenCapture.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include "_GDIPlus_BitmapApplyFilter.au3" Global Const $hDLL = _GDIPlus_BitmapApplyFilter_Open() Global Const $hGUI = GUICreate("Low-Polygon Maker v0.50", 252, 688, 4, 150, -1, $WS_EX_TOPMOST) GUISetFont(8, 400, 0, "Consolas") GUISetBkColor(0xABCDEF, $hGUI) Global $aRet = _GDIPlus_BitmapCreateVerticalText("Coded by UEZ 2026", 21.75, "Consolas", 0x380000FF, 1) Global Const $iPic_Label = GUICtrlCreatePic("", 204, 88, $aRet[1], $aRet[2]) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_Label, $STM_SETIMAGE, $IMAGE_BITMAP, $aRet[0])) Global Const $iLbl_Title = GUICtrlCreateLabel("Low-Polygon Maker", 0, 8, 238, 32, $SS_CENTER) GUICtrlSetFont(-1, 18, 400, 0, "Consolas") Global Const $iLbl_EdgeDetection = GUICtrlCreateLabel("Edge Detection", 4, 58, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iCombo_EdgeDetection = GUICtrlCreateCombo("", 96, 56, 145, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetData($iCombo_EdgeDetection, "SOBEL|" & _ "SCHARR|" & _ "PREWITT|" & _ "FREI_CHEN|" & _ "ROBERTS_CROSS|" & _ "ROBINSON_COMPASS|" & _ "KAYYALI|" & _ "RIDGE_DETECTION|" & _ "DIAGONAL_EDGES|" & _ "SOVELVSPREWITT|" & _ "OUTLINE3X3|" & _ "LAPLACE3x3_1|" & _ "LAPLACE3x3_2|" & _ "LAPLACE5x5|" & _ "EDGE_DETECTION1|" & _ "EDGE_DETECTION2|" & _ "EDGE_DETECTION3|" & _ "EDGE_DETECTION4|" & _ "EDGE_DETECTION5|" & _ "EMBOSS1|" & _ "EMBOSS2|" & _ "EMBOSS3|" & _ "EMBOSS4|" & _ "KIRSCH|" & _ "ISOTROPIC_SOBEL", _ "DIAGONAL_EDGES") Global $iInp_x = 96, $iInp_w = 100 Global Const $iLbl_Threshold = GUICtrlCreateLabel("ED Threshold", 4, 96, 76, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Threshold = GUICtrlCreateInput(0.35, $iInp_x, 92, $iInp_w, 21) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_Blur = GUICtrlCreateLabel("Blur Level", 4, 128, 64, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Blur = GUICtrlCreateInput(4, $iInp_x, 124, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_Colors = GUICtrlCreateLabel("Max. Colors", 4, 160, 70, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Colors = GUICtrlCreateInput(32, $iInp_x, 156, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_MinSpace = GUICtrlCreateLabel("Min Space", 4, 192, 58, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_MinSpace = GUICtrlCreateInput(4, $iInp_x, 188, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_MaxSpace = GUICtrlCreateLabel("Max Space", 4, 224, 58, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_MaxSpace = GUICtrlCreateInput(8, $iInp_x, 220, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_BorderSpaceX = GUICtrlCreateLabel("Border Space X", 4, 256, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_BorderSpaceX = GUICtrlCreateInput(2, $iInp_x, 252, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_BorderSpaceY = GUICtrlCreateLabel("Border Space Y", 4, 288, 88, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_BorderSpaceY = GUICtrlCreateInput(2, $iInp_x, 284, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_Alpha = GUICtrlCreateLabel("Edges Alpha", 4, 320, 70, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_Alpha = GUICtrlCreateInput(32, $iInp_x, 316, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") Global Const $iLbl_PosterizeLvl = GUICtrlCreateLabel("Posterize Lvl", 4, 352, 80, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iInp_PosterizeLvl = GUICtrlCreateInput(8, $iInp_x, 348, $iInp_w, 21, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) GUICtrlSetFont(-1, 10, 400, 0, "Consolas") GUICtrlSetTip(-1, "When the posterization level is set, the value for “Max. Colors” is ignored.") Global Const $iChkB_ShowEdges = GUICtrlCreateCheckbox("Show Edges", 4, 386, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") GUICtrlSetState(-1, $GUI_CHECKED) Global Const $iChkB_Wireframe = GUICtrlCreateCheckbox("Show Wireframes only", 4, 414, 233, 17) GUICtrlSetFont(-1, 8.5, 400, 0, "Consolas") Global Const $iBtn_Apply = GUICtrlCreateButton("&Apply", 8, 448, 235, 57) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) Global Const $iBtn_Load = GUICtrlCreateButton("&Load Image", 8, 520, 235, 57) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) Global Const $iBtn_Save = GUICtrlCreateButton("&Save Image", 8, 592, 235, 57) GUICtrlSetFont(-1, 12, 400, 0, "Consolas") GUICtrlSetBkColor(-1, 0xCCCCFF) Global $aParts[1] = [-1] Global Const $hStatusBar = _GUICtrlStatusBar_Create($hGUI, $aParts, "Ready") GUISetState(@SW_SHOW) GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND') Global $aMsg, $hImage, $sImgFile, $hGUI_Display = 0, $hGDI_LowPoly, $sFileLowPoly While 1 $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $hGUI Switch $aMsg[0] Case $GUI_EVENT_CLOSE GUIDelete($hGUI) _GDIPlus_BitmapApplyFilter_Close() Exit Case $iBtn_Load $sImgFile = FileOpenDialog("Select a GDI+ supported image", "", "Images (*.bmp;*.gif;*.png;*.jpg;*.tif)", $FD_FILEMUSTEXIST, "", $hGUI) If @error Then ContinueLoop If Not FileExists($sImgFile) Then MsgBox($MB_ICONERROR, "Error", $sImgFile & " doesn't exist", 30) ContinueLoop EndIf If $hImage Then _GDIPlus_ImageDispose($hImage) $hImage = _GDIPlus_ImageLoadFromFile($sImgFile) If Not $hImage Then MsgBox($MB_ICONERROR, "Error", "Unable to load file to GDI+", 30) ContinueLoop EndIf EncodeAndDisplay($hImage) Case $iBtn_Save If $sImgFile = "" Or $hGDI_LowPoly = 0 Then ContinueLoop $sFileLowPoly = FileSaveDialog("Save Low-Polygone Image", "", "Images (*.bmp;*.gif;*.png;*.jp?g;*.tif?)", 0, StringRegExpReplace($sImgFile, "^.*\\([^\\]+)(\.[^.]+)$", "\1_Low-Polygon\2"), $hGUI) If @error Or $sFileLowPoly = "" Then ContinueLoop If _ScreenCapture_SaveImage($sFileLowPoly, $hGDI_LowPoly, False) Then MsgBox($MB_ICONINFORMATION, "Information", "Low-Poly image saved.", 15, $hGUI) Else MsgBox($MB_ICONERROR, "Error", "Low-Poly image could not be save!", 15, $hGUI) EndIf Case $iBtn_Apply If $sImgFile = "" Or $hImage = 0 Then ContinueLoop EncodeAndDisplay($hImage) EndSwitch Case $hGUI_Display Switch $aMsg[0] Case $GUI_EVENT_CLOSE GUIDelete($hGUI_Display) $hGUI_Display = 0 EndSwitch EndSwitch WEnd Func EncodeAndDisplay($hImage) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) If $iW = 0 Or $iH = 0 Then Return SetError(1, 0, 0) Static $iWp = 0, $iHp = 0, $iPic_LowPoly If $iW <> $iWp Or $iH <> $iHp Then If $hGUI_Display Then GUIDelete($hGUI_Display) $hGUI_Display = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, $WS_EX_OVERLAPPEDWINDOW) $iPic_LowPoly = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) GUISetState(@SW_SHOWNA, $hGUI_Display) EndIf $iWp = $iW $iHp = $iH If $hGDI_LowPoly Then _WinAPI_DeleteObject($hGDI_LowPoly) $hGDI_LowPoly = 0 ;~ ConsoleWrite("Blur level: " & Number(GUICtrlRead($iInp_Blur)) & @CRLF & _ ;~ "Kernel: " & Execute("$" & GUICtrlRead($iCombo_EdgeDetection)) & @CRLF & _ ;~ "Threshold: " & Number(GUICtrlRead($iInp_Threshold), $NUMBER_DOUBLE) & @CRLF & _ ;~ "Amount of Colors: " & Number(GUICtrlRead($iInp_Colors)) & @CRLF & _ ;~ "Min Space: " & Number(GUICtrlRead($iInp_MinSpace)) & @CRLF & _ ;~ "Max Space: " & Number(GUICtrlRead($iInp_MaxSpace)) & @CRLF & _ ;~ "Border Space X: " & Number(GUICtrlRead($iInp_BorderSpaceX)) & @CRLF & _ ;~ "Border Space Y: " & Number(GUICtrlRead($iInp_BorderSpaceY)) & @CRLF & _ ;~ "Show Edges Checked: " & Int(BitAND(GUICtrlRead($iChkB_ShowEdges), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF & _ ;~ "Alpha Value: " & Number(GUICtrlRead($iInp_Alpha)) & @CRLF & _ ;~ "Wireframe Checked: " & Int(BitAND(GUICtrlRead($iChkB_Wireframe), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF & _ ;~ "Posterize level: " & Number(GUICtrlRead($iInp_PosterizeLvl)) & @CRLF & _ ;~ "GIF Mode Checked: " & Int(BitAND(GUICtrlRead($iChkB_GIFMode), $GUI_CHECKED) = $GUI_CHECKED) & @CRLF) ;~ ConsoleWrite("-----------------------------------------------------------------------" & @CRLF) Local $fTimer = TimerInit() $hGDI_LowPoly = _GDIPlus_BitmapApplyFilter_Delaunay3($hImage, Number(GUICtrlRead($iInp_Blur)), _ Execute("$" & GUICtrlRead($iCombo_EdgeDetection)), _ Number(GUICtrlRead($iInp_Threshold), $NUMBER_DOUBLE), _ Number(GUICtrlRead($iInp_Colors)), _ Number(GUICtrlRead($iInp_MinSpace)), _ Number(GUICtrlRead($iInp_MaxSpace)), _ Number(GUICtrlRead($iInp_BorderSpaceX)), _ Number(GUICtrlRead($iInp_BorderSpaceY)), _ Int(BitAND(GUICtrlRead($iChkB_ShowEdges), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_Alpha)), _ Int(BitAND(GUICtrlRead($iChkB_Wireframe), $GUI_CHECKED) = $GUI_CHECKED), _ Number(GUICtrlRead($iInp_PosterizeLvl)), _ 0, _ True) If $hGDI_LowPoly = 0 Then GUIDelete($hGUI_Display) $hGUI_Display = 0 Return SetError(1, 0, 0) EndIf _GUICtrlStatusBar_SetText($hStatusBar, "Generated in: " & Round(TimerDiff($fTimer), 2) & " ms", 0, $SBT_POPOUT) Local $hHBmp = GUICtrlSendMsg($iPic_LowPoly, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDI_LowPoly) If $hHBmp Then _WinAPI_DeleteObject($hHBmp) _WinAPI_InvalidateRect($hGUI_Display) _WinAPI_RedrawWindow($hGUI_Display) EndFunc ;==>EncodeAndDisplay Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam) Local $iNotifyCode = BitShift($wParam, 16) Local $iCtrlID = BitAND($wParam, 0x0000FFFF) Local $var If $iNotifyCode = $EN_KILLFOCUS Then Switch $iCtrlID Case $iInp_Blur $val = GUICtrlRead($iInp_Blur) If $val = "" Then $val = 4 $val = Number($val) If $val < 1 Then $val = 1 If $val > 127 Then $val = 127 GUICtrlSetData($iInp_Blur, $val) Case $iInp_Threshold $val = GUICtrlRead($iInp_Threshold) If $val = "" Then $val = 0.35 $val = Number($val) If $val < 0 Then $val = 0 If $val > 10 Then $val = 10 GUICtrlSetData($iInp_Threshold, StringFormat("%.2f", $val)) Case $iInp_Colors $val = GUICtrlRead($iInp_Colors) If $val = "" Then $val = 32 $val = Number($val) If $val < 2 Then $val = 2 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_Colors, $val) Case $iInp_MinSpace $val = GUICtrlRead($iInp_MinSpace) If $val = "" Then $val = 3 $val = Number($val) If $val < 1 Then $val = 1 GUICtrlSetData($iInp_MinSpace, $val) Case $iInp_MaxSpace $val = GUICtrlRead($iInp_MaxSpace) If $val = "" Then $val = 8 $val = Number($val) If $val < 1 Then $val = 1 GUICtrlSetData($iInp_MaxSpace, $val) Case $iInp_BorderSpaceX, $iInp_BorderSpaceY $val = GUICtrlRead($iCtrlID) If $val = "" Then $val = 2 $val = Number($val) If $val < 1 Then $val = 1 If $val > 255 Then $val = 255 GUICtrlSetData($iCtrlID, $val) Case $iInp_Alpha $val = GUICtrlRead($iInp_Alpha) If $val = "" Then $val = 32 $val = Number($val) If $val < 0 Then $val = 0 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_Alpha, $val) Case $iInp_PosterizeLvl $val = GUICtrlRead($iInp_PosterizeLvl) If $val = "" Then $val = 8 $val = Number($val) If $val < 1 Then $val = 1 If $val > 255 Then $val = 255 GUICtrlSetData($iInp_PosterizeLvl, $val) EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_WM_COMMAND Func _GDIPlus_BitmapCreateVerticalText($sString, $fFontSize = 10, $sFont = "Arial", $iColor_Text = 0xFF000000, $iFlip = 3) $iFlip = $iFlip <> 3 Or $iFlip <> 1 ? 3 : $iFlip _GDIPlus_Startup() Local Const $hDC = _WinAPI_GetWindowDC(0) Local Const $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC) Local Const $hBrush = _GDIPlus_BrushCreateSolid($iColor_Text) Local Const $hFormat = _GDIPlus_StringFormatCreate() Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFont) Local Const $hFont = _GDIPlus_FontCreate($hFamily, $fFontSize) Local $tLayout = _GDIPlus_RectFCreate() Local Const $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sString, $hFont, $tLayout, $hFormat) Local $iError = 1 If Not @error Then Local Const $iW = Ceiling($aInfo[0].Width), $iH = Ceiling($aInfo[0].Height) Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH), $hCanvas = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hCanvas, $GDIP_TEXTRENDERINGHINTANTIALIASGRIDFIT) $tLayout.X = 0 $tLayout.Y = 0 $tLayout.Width = $iW $tLayout.Height = $iH _GDIPlus_GraphicsDrawStringEx($hCanvas, $sString, $hFont, $tLayout, $hFormat, $hBrush) _GDIPlus_ImageRotateFlip($hBitmap, $iFlip) Local Const $hBitmap_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _GDIPlus_GraphicsDispose($hCanvas) _GDIPlus_BitmapDispose($hBitmap) $iError = 0 EndIf _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_ReleaseDC(0, $hDC) _GDIPlus_Shutdown() If $iError Then Return SetError(1, 0, 0) Local $aResult[3] = [$hBitmap_GDI, $iH, $iW] Return $aResult EndFunc ;==>_GDIPlus_BitmapCreateVerticalText Examples: The required DLLs (_GDIPlus_BitmapApplyFilter.dll / _GDIPlus_BitmapApplyFilter_x64.dll) and _GDIPlus_BitmapApplyFilter.au3 can be found on my OneDrive: _GDIPlus_BitmapApplyFilter Edited 6 hours ago by UEZ mLipok, SOLVE-SMART, argumentum and 1 other 2 2 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
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