Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/14/2024 in all areas

  1. Hi, the reason for these "artefacts" is the accumulation of all rounding errors caused by the use of byte "colours" aka AARRGGBB. You will get better results when you calculate only with floating numbers. Unfortunately AutoIt is not able to "cast" a hex value into a float number (or i cannot remember it ^^), DEC() is able to cast hex into double but double is 64bit and does`nt fit into a 32bit "Pixel" AARRGGBB First to do is to store "floats" instead of AARRGGBB within the whole image Get the pixel value via _GDIPlus_BitmapGetPixel(), write this value into a dword struct which is on the same address as a float struct and read the dword (aka float) $floatstruct = DllStructCreate("float") $dwordstruct = DllStructCreate("dword", DllStructGetPtr($floatstruct)) ;AARRGGBB to float For $y = 0 To $Height - 1 For $x = 0 To $Width - 1 $oldPixel = Dec(Hex(_GDIPlus_BitmapGetPixel($Image, $x, $y), 2)) / 255 ;get float number between 0 and 1 DllStructSetData($floatstruct, 1, $oldPixel) ;write into float struct $oldPixel = DllStructGetData($dwordstruct, 1) ;read as dword (aka "pixel" AARRGGBB) _GDIPlus_BitmapSetPixel($Image, $x, $y, $oldPixel) ;store the float number as "pixel" AARRGGBB Next Next Now the "image" is an array of floats. In the next step you have to read the floating point numbers (aka oldpixel) via _GDIPlus_BitmapGetPixel(), calculate if more or less than 0.5 and set the newpixel value and set the the black or white pixel in the image and the quant_error For $y = 0 To $Height - 1 For $x = 0 To $Width - 1 $oldPixel = _GDIPlus_BitmapGetPixel($Image, $x, $y) ;pixel as dword DllStructSetData($dwordstruct, 1, $oldPixel) ;write into dwordstruct (place of floatstruct) $oldPixel = DllStructGetData($floatstruct, 1) ;read float If $oldPixel <= 0.5 Then $newpixel = 0 Else $newpixel = 1 EndIf _GDIPlus_BitmapSetPixel($Image, $x, $y, String("0xFF" & Hex($newpixel * 255, 2) & Hex($newpixel * 255, 2) & Hex($newpixel * 255, 2))) $quant_error = $oldPixel - $newpixel Now Floyd-Steinberg: As mentioned before, other languages can handle images and floating point numbers, I transferred dwords and floats via DllStructs. ;-------Floyd-Steinberg $pixel = _GDIPlus_BitmapGetPixel($Image, $x + 1, $y);get pixel integer/DWORD AARRGGBB DllStructSetData($dwordstruct, 1, $pixel) ;set into DWORD struct $col = DllStructGetData($floatstruct, 1) ;read float from DWORD $float = $col + (7 / 16 * $quant_error) ;calculate with float DllStructSetData($floatstruct, 1, $float) ;write into float struct $pixel = DllStructGetData($dwordstruct, 1) ;get dword from float and _GDIPlus_BitmapSetPixel($Image, $x + 1, $y, $pixel) ;write the "float" as a "pixel" which leads to the script: ;$aligncomment=60 #include <GDIPlus.au3> HotKeySet("{ESC}", "_exit") _GDIPlus_Startup() Global $Image = _GDIPlus_BitmapCreateFromFile("graytest.png") ;~ Global $Image = _GDIPlus_BitmapCreateFromFile("dithercompare.png") ;~ Global $Image = _GDIPlus_BitmapCreateFromFile("test50.png") Global $Width = _GDIPlus_ImageGetWidth($Image), $Height = _GDIPlus_ImageGetHeight($Image) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Height = ' & $Height & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Width = ' & $Width & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console $Gui = GUICreate("Floyd-Steinberg Dithering", $Width, $Height) GUISetState() $Graphics = _GDIPlus_GraphicsCreateFromHWND($Gui) _GDIPlus_GraphicsDrawImageRect($Graphics, $Image, 0, 0, $Width, $Height) $floatstruct = DllStructCreate("float") $dwordstruct = DllStructCreate("dword", DllStructGetPtr($floatstruct)) ;AARRGGBB to float For $y = 0 To $Height - 1 For $x = 0 To $Width - 1 $oldPixel = Dec(Hex(_GDIPlus_BitmapGetPixel($Image, $x, $y), 2)) / 255 ;get float number between 0 and 1 DllStructSetData($floatstruct, 1, $oldPixel) ;write into float struct $oldPixel = DllStructGetData($dwordstruct, 1) ;read as dword (aka "pixel" AARRGGBB) _GDIPlus_BitmapSetPixel($Image, $x, $y, $oldPixel) ;store the float number as "pixel" AARRGGBB Next Next _GDIPlus_GraphicsDrawImageRect($Graphics, $Image, 0, 0, $Width, $Height) ;show image with "floats" For $y = 0 To $Height - 1 For $x = 0 To $Width - 1 $oldPixel = _GDIPlus_BitmapGetPixel($Image, $x, $y) ;pixel as dword DllStructSetData($dwordstruct, 1, $oldPixel) ;write into dwordstruct (place of floatstruct) $oldPixel = DllStructGetData($floatstruct, 1) ;read float If $oldPixel <= 0.5 Then $newpixel = 0 Else $newpixel = 1 EndIf _GDIPlus_BitmapSetPixel($Image, $x, $y, String("0xFF" & Hex($newpixel * 255, 2) & Hex($newpixel * 255, 2) & Hex($newpixel * 255, 2))) $quant_error = $oldPixel - $newpixel ;-------Floyd-Steinberg $pixel = _GDIPlus_BitmapGetPixel($Image, $x + 1, $y);get pixel integer/DWORD AARRGGBB DllStructSetData($dwordstruct, 1, $pixel) ;set into DWORD struct $col = DllStructGetData($floatstruct, 1) ;read float from DWORD $float = $col + (7 / 16 * $quant_error) ;calculate with float DllStructSetData($floatstruct, 1, $float) ;write into float struct $pixel = DllStructGetData($dwordstruct, 1) ;get dword from float and _GDIPlus_BitmapSetPixel($Image, $x + 1, $y, $pixel) ;write the "float" as a "pixel" $pixel = _GDIPlus_BitmapGetPixel($Image, $x - 1, $y + 1) DllStructSetData($dwordstruct, 1, $pixel) ;set into DWORD struct $col = DllStructGetData($floatstruct, 1) ;read float from DWORD $float = $col + (3 / 16 * $quant_error) ;calculate with float DllStructSetData($floatstruct, 1, $float) ;write into float struct $pixel = DllStructGetData($dwordstruct, 1) ;get dword from float and _GDIPlus_BitmapSetPixel($Image, $x - 1, $y + 1, $pixel) $pixel = _GDIPlus_BitmapGetPixel($Image, $x, $y + 1) DllStructSetData($dwordstruct, 1, $pixel) ;set into DWORD struct $col = DllStructGetData($floatstruct, 1) ;read float from DWORD $float = $col + (5 / 16 * $quant_error) ;calculate with float DllStructSetData($floatstruct, 1, $float) ;write into float struct $pixel = DllStructGetData($dwordstruct, 1) ;get dword from float and _GDIPlus_BitmapSetPixel($Image, $x, $y + 1, $pixel) $pixel = _GDIPlus_BitmapGetPixel($Image, $x + 1, $y + 1) DllStructSetData($dwordstruct, 1, $pixel) ;set into DWORD struct $col = DllStructGetData($floatstruct, 1) ;read float from DWORD $float = $col + (1 / 16 * $quant_error) ;calculate with float DllStructSetData($floatstruct, 1, $float) ;write into float struct $pixel = DllStructGetData($dwordstruct, 1) ;get dword from float and _GDIPlus_BitmapSetPixel($Image, $x + 1, $y + 1, $pixel) Next _GDIPlus_GraphicsDrawImageRect($Graphics, $Image, 0, 0, $Width, $Height) ; to see the errors quick instead of waiting for the whole image Next _GDIPlus_GraphicsDrawImageRect($Graphics, $Image, 0, 0, $Width, $Height) While GUIGetMsg <> -3 Sleep(10) WEnd Func _exit() Exit EndFunc ;==>_exit Interesting side effect: If an image is filled with 50% gray the result of Floyd-Steinberg should be a checkboard pattern. In the "real world", floating point numbers have restrictions, mentioned hundrets of thousands of times here in this forum.... So at the end, in the "real world" (of floating point numbers) there is an error which shows some artefacts in the "checkboard" pattern ( 50% gray as test50.png). These errors are inevitably and independant of the used computer language. Floyd Steinberg dithering.zip
    2 points
  2. Here. You should also consider to toggle check all to uncheck all. Case $xCheck For $i = 0 To _GUICtrlListView_GetItemCount($cList) - 1 _GUICtrlListView_SetItemChecked($cList, $i, GUICtrlRead($xCheck) = $GUI_CHECKED) Next
    1 point
  3. 1 point
  4. Jos

    Issue with Scite/Abbrev

    Thats what i assumed, so am considering it fixed in the current beta. :-)
    1 point
  5. donnyh13

    Issue with Scite/Abbrev

    @Jos, in case it helps, in 4.4.6 I can reproduce the error the @Nine references by pushing ctrl+b after CW in the below line: cw@Compiled "ctrl+b" cw@compiled@Compiled But in the new Beta, it doesn't do it.
    1 point
  6. The 10/10 rating for this is highly inaccurate, that should only be reserved for fully remote arbitrary code execution. I agree with the points made in this video:
    1 point
  7. ioa747

    _ArrayFindAll help needed

    RegExpQuickTester 2.5p will help #include <Array.au3> Local $aArray[5][5] = [[0, 1, 2, 1, 0], _ [125, "5|12", 5, 4, 2], _ ["4|12", 122, 3, "1|12", 3], _ [0, 3, "2|13", 1, 0], _ [12, 5, 5, 4, 1]] ;~ _ArrayDisplay($aArray, "2D array") Local $aResult = _ArrayFindAll($aArray, "\b12\b", Default, Default, Default, 3, 0) _ArrayDisplay($aResult, "Found in Column 0") $aResult = _ArrayFindAll($aArray, "\b12\b", Default, Default, Default, 3, 2, True) _ArrayDisplay($aResult, "Found in Row 2") Tip: a small sample of your array would help so we don't have to imagine or write about it Edit: from 12(?:\d*) to \b12\b because 12(?:\d*) would also catch 121
    1 point
  8. Getting old , and overworked 🥺. Will answer ASAP , when back from weekend vacation.
    1 point
  9. ioa747

    Round buttons

    Method for Colorful Rectangle Buttons ; https://www.autoitscript.com/forum/topic/211721-round-buttons/ ;---------------------------------------------------------------------------------------- ; Title...........: RectButtonsSpecial.au3 ; Description.....: collection of rectangles buttons - Special Edition ; AutoIt Version..: 3.3.16.1 Author: ioa747 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GUIConstantsEx.au3> #include <StaticConstants.au3> ; ~~~~~~~~~~~~~~~~~ Example - what is ColorLight() Global $test = ColorLight(0xC800C8, 50) ConsoleWrite($test & @CRLF) $test = ColorLight(0xC800C8, 50, 1) ConsoleWrite($test & @CRLF) $test = ColorLight(0xC800C8, 50, 2) ConsoleWrite(StringFormat("RGB(%d,%d,%d)", $test[0], $test[1], $test[2]) & @CRLF & @CRLF) ; ~~~~~~~~~~~~ End of Example - what is ColorLight() Global $MyGui, $aBtn[6][2], $btnColor = 0xC800C8 $MyGui = GUICreate(@ScriptName, 180, 220) GUISetBkColor(0x000000) $aBtn[0][0] = 5 ; cnt of buttons $aBtn[1][0] = GUICtrlCreateLabel("Button1", 10, 20, 150, 30, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0xFFFFFF) $aBtn[1][1] = 0xA64500 GUICtrlSetBkColor(-1, $aBtn[1][1]) $aBtn[2][0] = GUICtrlCreateLabel("Button2", 10, 60, 150, 30, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0xFFFFFF) $aBtn[2][1] = 0x826E00 GUICtrlSetBkColor(-1, $aBtn[2][1]) $aBtn[3][0] = GUICtrlCreateLabel("Button3", 10, 100, 150, 30, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0xFFFFFF) $aBtn[3][1] = 0x268000 GUICtrlSetBkColor(-1, $aBtn[3][1]) $aBtn[4][0] = GUICtrlCreateLabel("Button4", 10, 140, 150, 30, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0xFFFFFF) $aBtn[4][1] = 0x0094FF GUICtrlSetBkColor(-1, $aBtn[4][1]) $aBtn[5][0] = GUICtrlCreateLabel("Button5", 10, 180, 150, 30, BitOR($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif") GUICtrlSetColor(-1, 0xFFFFFF) $aBtn[5][1] = 0x9600D5 GUICtrlSetBkColor(-1, $aBtn[5][1]) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch _IsOver() WEnd ;-------------------------------------------------------------------------------------------------------------------------------- Func _IsOver() Local Static $iActive, $iClicked = 0 Local $aActive = GUIGetCursorInfo($MyGui) If $aActive[2] And $iClicked = 1 Then Return If $iActive <> $aActive[4] And $iClicked = 0 Then $iActive = $aActive[4] For $i = 1 To $aBtn[0][0] If $aBtn[$i][0] = $aActive[4] Then GUICtrlSetBkColor($aBtn[$i][0], ColorLight($aBtn[$i][1], 30)) ;hover Else GUICtrlSetBkColor($aBtn[$i][0], $aBtn[$i][1]) ;normal EndIf Next EndIf If $aActive[2] Or $iClicked = 1 Then For $i = 1 To $aBtn[0][0] If $aBtn[$i][0] = $iActive Then If $iClicked = 0 Then GUICtrlSetBkColor($aBtn[$i][0], ColorLight($aBtn[$i][1], -30)) ;click GUICtrlSetFont($aBtn[$i][0], 10, 800, 2, "MS Sans Serif") GUICtrlSetColor($aBtn[$i][0], 0xCCCCCC) $iClicked = 1 Else GUICtrlSetBkColor($aBtn[$i][0], ColorLight($aBtn[$i][1], 30)) ;hover GUICtrlSetFont($aBtn[$i][0], 10, 800, 0, "MS Sans Serif") GUICtrlSetColor($aBtn[$i][0], 0xFFFFFF) $iClicked = 0 _ButtonCaller($aBtn[$i][0]) EndIf EndIf Next EndIf EndFunc ;==>_IsOver ;-------------------------------------------------------------------------------------------------------------------------------- Func _ButtonCaller($Btn) Switch $Btn Case $aBtn[1][0] ConsoleWrite(GUICtrlRead($aBtn[1][0]) & @CRLF) Case $aBtn[2][0] ConsoleWrite(GUICtrlRead($aBtn[2][0]) & @CRLF) Case $aBtn[3][0] ConsoleWrite(GUICtrlRead($aBtn[3][0]) & @CRLF) Case $aBtn[4][0] ConsoleWrite(GUICtrlRead($aBtn[4][0]) & @CRLF) Case $aBtn[5][0] ConsoleWrite(GUICtrlRead($aBtn[5][0]) & @CRLF) Case $aBtn[6][0] ConsoleWrite(GUICtrlRead($aBtn[6][0]) & @CRLF) EndSwitch EndFunc ;==>_ButtonCaller ; #FUNCTION# -------------------------------------------------------------------------------------------------------------------- ; Name...........: ColorLight() ; Description....: Returns a new color that is a combination of the $HexColor plus the amount of $Lightness it adds to all three RGB channels. ; Syntax.........: ColorLight($HexColor [, $Lightness [,$output]]) ; Parameters.....: $HexColor - The start color to be combined. ; $Lightness - The amount it adds to all three RGB channels. Negative number to subtract (darker) ; $output - Optional: The format of the output string: ; 0 = "0x" followed by the hexadecimal value of the new color (default) ; 1 = "#" followed by the hexadecimal value of the new color ; 2 = an array containing the red, green and blue values of the new color ; Return values..: The new color as a string or an array. ; Author ........: ioa747 ; Notes .........: ;-------------------------------------------------------------------------------------------------------------------------------- Func ColorLight($HexColor, $Lightness = 0, $sOutput = 0) If StringLeft($HexColor, 1) = "#" Then $HexColor = StringReplace($HexColor, "#", "0x") Local $sHexColor = Hex($HexColor, 6) ;ConsoleWrite("$sHexColor=" & $sHexColor & @CRLF) Local $aSplit = StringSplit($sHexColor, "") Local $aRGB[3] If $aSplit[0] = 6 Then $aRGB[0] = Dec($aSplit[1] & $aSplit[2], 0) $aRGB[1] = Dec($aSplit[3] & $aSplit[4], 0) $aRGB[2] = Dec($aSplit[5] & $aSplit[6], 0) ;ConsoleWrite(StringFormat("aRGB(%d,%d,%d)", $aRGB[0], $aRGB[1], $aRGB[2]) & @CRLF) Else ConsoleWrite("Something wrong $aSplit[0]=" & $aSplit[0] & @CRLF) Return SetError(1, 0, -1) EndIf Local $aNewRGB[] = [$aRGB[0] + $Lightness, $aRGB[1] + $Lightness, $aRGB[2] + $Lightness] If $aNewRGB[0] < 0 Then $aNewRGB[0] = 0 If $aNewRGB[0] > 255 Then $aNewRGB[0] = 255 If $aNewRGB[1] < 0 Then $aNewRGB[1] = 0 If $aNewRGB[1] > 255 Then $aNewRGB[1] = 255 If $aNewRGB[2] < 0 Then $aNewRGB[2] = 0 If $aNewRGB[2] > 255 Then $aNewRGB[2] = 255 ;ConsoleWrite(StringFormat("aNewRGB(%d,%d,%d)", $aNewRGB[0], $aNewRGB[1], $aNewRGB[2]) & @CRLF) Local $sColor ;$sOutput: 0:="0x" | 1:="#" | 2:=aRGB[R,G,B] Switch $sOutput Case 0, 1 $sColor = ($sOutput = 1 ? "#" : "0x") $sColor &= Hex(String($aNewRGB[0]), 2) $sColor &= Hex(String($aNewRGB[1]), 2) $sColor &= Hex(String($aNewRGB[2]), 2) ;ConsoleWrite("$sColor=" & $sColor & @CRLF & @CRLF) Case 2 $sColor = $aNewRGB EndSwitch Return $sColor EndFunc ;==>ColorLight ;-------------------------------------------------------------------------------------------------------------------------------- have fun Thank you very much
    1 point
  10. Hello, I have this code : While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $close, $btnClose MsgBox(0, '', "exit ok") Exit Case Else $checkclose = _WaitForImageSearch("IMG/Close.jpg", 40, 1, 150, 0) EndSwitch WEnd Please my problem is easy, how to close windows before a image is found and finish to wait 40s. Since 2 or 3 years i search how to make Thank you
    0 points
×
×
  • Create New...