-
Posts
409 -
Joined
-
Last visited
-
Days Won
4
Everything posted by AndyG
-
Yes, and much more advantage if one knows the "bitmap" FILE ( ! ) format? Skip the first 54 bytes (file header) and you will find....the "pixels" aka image data pixelarray (depending on the 1/2/4/8/16/24/32 Bit per Pixel mode (see header...)). So no need to CreateBitmapFromFile() because a simple "open" file gives access to the pixel data array.... Go and get the first "line" of the bitmap (as a char-string) and search in the screenshot (transfer the screenshot-bytes into a char-array...others say "string") with StringInstr(). If the first line of the bitmap is found in the screenshot, the comparison of the next "line" in the bitmap with the next "line" in the screenshot is easy. Because the position of the text ( a char-array ist the same as a byte array) is known in the screenshot-"text", the comparison with the next "lines" is only a comparison of "text" (StringMid() is our friend) . I have written a few example scripts with this method to find a "bitmap in a bitmap". I have to look for them at the weekend Speed-challenge opened!
-
Haha...thx, i made this centuries ago...if I remember right, it was a contribution to some other "digital desktop clock" scripts which took some hundret lines of code...my intention was to write a script in less than 50 lines of code. The "bitbanging" aka producing a polygon, means the position and orientation of an "equal shape", I taught myself about 40 years ago when I programmed "graphical" games for a calculator (sharp PC1401) with a 7-segment LC display in machine code. yepp, rotation is the key...and it is not necessary to use "graphical stuff" like GDI(+) or something like that to read or write "pixels"! A bitmap is an array of bytes/words/dwords representing the "pixels". If you put an AutoIt dllstruct "over" a bitmap (at the bitmap's starting address in memory), you can read or write "pixels" with a simple DllStructGetData() / DllStructSetData(), or, much faster, define/read the dllstruct as a "string" (characters) and use the super-fast AutoIt string commands like StringInstr() to locate a specific sequence of "bytes" (characters). As Werty mentioned, the first column of the digit is unique. This requires seven "bit tests" due to the way the pixels are arranged in memory, as each "pixel" is in a different area of the bitmap. After rotating the image, only one test is required, as the "pixels" of the first column are now in a row, one after the other. So only one read from memory is required to get the "number". And since the position of the next "number" on the screen is known in the bitmap's memory, a search for a sequence of 4 consecutive "numbers" would only require 4 reads from memory. This means that the first step is to look for the first "digit", then look at the (known) next position in memory and check if the byte at that position is the second "digit", and so on... With this technique the search of a sequence of "numbers" on a screenshot is possible in a few (milli)-Seconds. In native AutoIt code....
-
Hi! if it has to look more like a "real" 7-segment ...how about this? (I wrote it many years ago....@UEZ, do you remember^^) #include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> Dim $ws[12] = [0, 0, 10, -7, 50, -7, 60, 0, 50, 7, 10, 7] ;Koordinaten Polygonzug: von links nach rechts WAAGRECHTER Balken, von rechts nach links SENKRECHTER Balken Dim $ziffer[10] = [239, 10, 118, 94, 154, 220, 253, 14, 254, 222] ;alle gesetzten bits des Indexes in der 7-segmentanzeige ergeben die Ziffer Dim $balkenpos[8] = [0, "60.0", "0.0", "60.60", "0.60", "0.60", "0.120", "0.0"] ;position der Leuchtbalken der 7-Segmentanzeige innerhalb der Ziffer Dim $p[7][2] ;nimmt die polygonzug-koordinaten zum Zeichnen auf $p[0][0] = 6 ;6 Punkte im Polygonzug _GDIPlus_Startup() Global $hgui = GUICreate('Uhr', 620, 175, -1, -1, $WS_POPUP) ;GUI erstellen ohne Rahmen Global $hWnd = WinGetHandle($hgui) ;Handle holen Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd) ;"Leinwand" erstellen, auf der gezeichnet werden kann GUICtrlCreateLabel("", 0, 0, 620, 175, Default, $GUI_WS_EX_PARENTDRAG) ;verschieben des Fensters möglich machen durch 2. Fenster GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ;das 2. Fenster transparent machen GUISetBkColor(0x000000) ;Hintergrund der GUI schwarz GUISetState() ;GUI anzeigen AdlibRegister("_time", 1000) ;jede Zehntelsekunde ein Refresh der Zeitanzeige Do ;Endlosschleife, solange bis.. Until GUIGetMsg() = -3 ;..ESC gedrückt wird _GDIPlus_GraphicsDispose($hGraphic) ;freigeben _GDIPlus_Shutdown() Func _time() ;Uhrzeit anzeigen :o) For $k = 1 To 6 ;die 6 Ziffern der Uhrzeit $setbits = $ziffer[StringMid(String(@HOUR & @MIN & @SEC), $k, 1)] ;gesetzte Bits in der siebensegmentanzeige anhand der Ziffer in der Uhrzeit holen For $bitnr = 7 To 1 Step -1 ;alle Bits durchlaufen _drawpolygon(BitAND($setbits, 128), $k * 100 - 80 + ($k = 1 Or $k = 3 Or $k = 5) * 20, $bitnr) ;parameter: bit gesetzt ja/nein, position der gesamten ziffer,nummer des bits(gerade=waagrechter balken, ungerade=senkrechter balken) $setbits = BitShift($setbits, -1) ;nächstes Bit holen Next Next $brush = _GDIPlus_BrushCreateSolid(0xFF440000 + (@SEC / 2 = Int(@SEC / 2)) * 0xBB0000) ;Pinsel erstellen, wenn Ziffer gerade, dann farbig, ansonsten schwarz _GDIPlus_GraphicsFillEllipse($hGraphic, 202, 55, 15, 15, $brush) ;Punkte zeichnen _GDIPlus_GraphicsFillEllipse($hGraphic, 402, 55, 15, 15, $brush) _GDIPlus_GraphicsFillEllipse($hGraphic, 202, 105, 15, 15, $brush) _GDIPlus_GraphicsFillEllipse($hGraphic, 402, 105, 15, 15, $brush) _GDIPlus_BrushDispose($brush) ;Pinsel auflösen EndFunc ;==>_time Func _drawpolygon($bit, $xpos, $bitnr) ;zeichnet einen polygonzug ("Balken") an die entsprechende Position $split = StringSplit($balkenpos[$bitnr], ".", 3) ;x- und y-koordinaten des Balkens innerhalb der Ziffer holen $b = (($bitnr / 2) = Int($bitnr / 2)) ;$bit gerade => $b = true => Balken waagrecht, ansonsten Balken senkrecht $step = -1 + 2 * $b ;schrittweite durch das $WS-Array For $i = 11 - 11 * $b To 11 * $b Step 2 * $step ;array mit waagrechten (bit=gerade) oder (Bit=ungerade) senkrechten Balken füllen $r = Int(Abs((11 * (Not ($b))) - $i) / 2) + 1 ;abhängig von der Reihenfolge, egal ob $i von 0 bis 11 oder von 11 bis 0, $r muss immer 1,2,3,4,5,6 $p[$r][0] = $ws[$i] + $split[0] + $xpos ;x- und $p[$r][1] = $ws[$i + $step] + $split[1] + 30 ;y-position in das polygonarray schreiben Next $brush = _GDIPlus_BrushCreateSolid(0xFF440000 + ($bit <> 0) * 0xBB0000) ;wenn bit gesetzt, dann farbig, ansonsten schwarz _GDIPlus_GraphicsFillPolygon($hGraphic, $p, $brush) ;Balken zeichnen _GDIPlus_BrushDispose($brush) EndFunc ;==>_drawpolygon If you want to know how it works....read the code!
-
Trouble with Floyd-Steinberg dithering
AndyG replied to Werty's topic in AutoIt General Help and Support
Hey UEZ, nice one as always ^^ I found a very cool python script here https://scipython.com/blog/floyd-steinberg-dithering/ After some tests I have realised that I can get similar results with your script when multiplying the $iColors with 3 (approximately^^). But with low numbers of $iColors, something strange is happening: Global $iColors = 16, $iDitherMode =1 Changing to $iColors = 17, $iDitherMode =1 , the result looks much better. What is the reason for that behaviour?- 19 replies
-
- dithering
- floyd-steinberg
-
(and 1 more)
Tagged with:
-
Trouble with Floyd-Steinberg dithering
AndyG replied to Werty's topic in AutoIt General Help and Support
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- 19 replies
-
- dithering
- floyd-steinberg
-
(and 1 more)
Tagged with:
-
@Andreik, yes, x-thousand times faster than "native" AutoItcode is not that bad! But there are, independent of the language/compiler you use, much more (possible) improvements. Depending on the size of the files to be compared and the available RAM, you could load the "golden pattern"-file (file to compare with) and then (in a loop) 15 files to compare. Why 15? There are 16 SSE/AVX-register (YMM0-YMM15 in x64-mode) available, each, you know it, 32 bytes wide. So you have to load the "golden pattern" only once and then then you are able to compare 32 byte(s) in the "source" to 32 bytes in each of the 15 loaded files. The loopcount is shortened by a factor of 32, also the number of comparisons by a factor of 15 ( per number of loaded files). Loop unrolling is implemented too Results in (lets forget the overhead and so it is better to calculate in my old brain ) ~30 * ~10 ~~ 300 times faster (comparing to your 27bytes long (I love it^^)) code! Not to mention all the file- and processorcache "goodies" you would benefit from. I'm sure there are many more, and faster, ways to accomplish such a "simple" task.....
-
Working Example Memory pointer reader and Get Base Address
AndyG replied to Jblz619's topic in AutoIt Example Scripts
Hi, compile a program "Get_Discord_Status_loaded_64Bit.exe" as a 64bit-application. Write the status into a file or return it elsewhere.... Compile a program "Get_Steam_Status_loaded_32Bit.exe" as a 32bit-application. Write the status into a file or return it elsewhere.... Compile your program as a 32/64bit-Application and evaluate the status from the file.- 11 replies
-
- memory pointer
- base address
-
(and 3 more)
Tagged with:
-
wcslen alternative for Binary string length from pointer
AndyG replied to jugador's topic in AutoIt General Help and Support
__ExampleA() Func __ExampleA() Local $BinaryString = StringToBinary("Hello @World") Local $Bin_Len = BinaryLen($BinaryString) ConsoleWrite('BinaryLen: ' & $Bin_Len & @TAB & 'BinaryString: ' & $BinaryString & @CRLF) Local $tSTRUCT1 = DllStructCreate('uint; Byte[' & $Bin_Len & ']') DllStructSetData($tSTRUCT1, 1, $Bin_Len, 1) For $i = 1 To $Bin_Len ;you have to write bytes...because it is not a string! or you can make a memcpy DllStructSetData($tSTRUCT1, 2, Dec(StringMid($BinaryString, $i * 2 + 1, 2)), $i) ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : stringmid($BinaryString,$i*2+1,2) = ' & StringMid($BinaryString, $i * 2 + 1, 2) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console Next ConsoleWrite('[Data uint ]: ' & DllStructGetData($tSTRUCT1, 1) & @CRLF) ConsoleWrite('[Data String ]: ' & DllStructGetData($tSTRUCT1, 2) & @CRLF) Local $pVariant = DllStructGetPtr($tSTRUCT1) ConsoleWrite('[$pVariant ]: ' & $pVariant & @CRLF & @CRLF & @CRLF) ;end of writing data into memory ;start reading data from memory with known pointer $struct_stringlen = DllStructCreate("uint", $pVariant) ;get first 4 bytes = uint =stringlen $stringlen = DllStructGetData($struct_stringlen, 1) ;lets get the binarystring $struct_binarystring = DllStructCreate("byte[" & $stringlen & "]", $pVariant + 4) ;place the struct at the pointer +4 because uint is 4 bytes $binary = DllStructGetData($struct_binarystring, 1) $string = BinaryToString($binary) ConsoleWrite(" Stringlen = " & $stringlen & @CRLF & " Binary = " & $binary & @CRLF & " String = " & $string & @crlf & @crlf) EndFunc ;==>__ExampleA If you have an ANSI/ASCII String, it is much easier because the transformation to binary data is omitted. You can write the (ANSI/ASCII) string directly into the memory. This works with char and wchar (16 bit unicode). __ExampleB() Func __ExampleB() Local $String = "Hello @World" Local $Len = StringLen($String) ConsoleWrite('StringLen: ' & $Len & @TAB & 'String: ' & $String & @CRLF) Local $tSTRUCT1 = DllStructCreate('uint; char[' & $Len & ']') ;or wchar if unicode!!! DllStructSetData($tSTRUCT1, 1, $Len) DllStructSetData($tSTRUCT1, 2, $String) ConsoleWrite('[Data uint ]: ' & DllStructGetData($tSTRUCT1, 1) & @CRLF) ConsoleWrite('[Data String ]: ' & DllStructGetData($tSTRUCT1, 2) & @CRLF) Local $pVariant = DllStructGetPtr($tSTRUCT1) ConsoleWrite('[$pVariant ]: ' & $pVariant & @CRLF & @CRLF & @CRLF) ;end of writing data into memory ;start reading data from memory with known pointer $struct_stringlen = DllStructCreate("uint", $pVariant) ;get first 4 bytes = uint =stringlen $stringlen = DllStructGetData($struct_stringlen, 1) ;lets get the string char or wchar if unicode $struct_string = DllStructCreate("char[" & $stringlen & "]", $pVariant + 4) ;place the struct at the pointer +4 because uint is 4 bytes $String = DllStructGetData($struct_string, 1) ConsoleWrite(" Stringlen = " & $stringlen & @CRLF & " String = " & $String & @CRLF & @CRLF) EndFunc ;==>__ExampleB -
wcslen alternative for Binary string length from pointer
AndyG replied to jugador's topic in AutoIt General Help and Support
Yes, use the appropriate string managemennt system. The pointer points to a memoryblock where the first 4 bytes (UINT/DWORD) contains the string length and the rest of the memory contains the string/data. Then the data format is irrelevant. -
Find out CPU (used) Time of processes.
AndyG replied to Jemboy's topic in AutoIt General Help and Support
Hi! Nice example of the XY-Problem! What the Problem is: What the User think the Problem is: No, you are lying to yourself! The MAIN problem is that the app is crashing....you need to fix THIS! You don't have to solve problems, you have to eliminate problems!- 7 replies
-
- cpu time
- task manager
-
(and 1 more)
Tagged with:
-
Oh no! Please use those >50 years old techniques more! I am always so impressed and surprised when examining/investigate such a piece of "gold" code😇 I played the "original" Sokoban in the 80s, it was fun at all! So thank you so much transferring the idea into AutoIt code!
-
63 Moves....but 50 Seconds needed....😁 And btw....xor al, 0x7f, SO CUTE!!😍
-
Hi! As always in this cases (I know what I am talking about 🐵 , sometimes I "don´t see the wood for the trees" also) ...look at what you are posting in the picture....you compare "Elvis" with "Elvis.mkv"...that doesn´t work 😃 You have to trim the extension ".mkv" from the title, thats all! In Line 190 $strMovieTitle = StringTrimRight($arrLocalLib [$i],4) ;trims the extension from filename
-
[SOLVED] Insert base64 image in XLS sheet
AndyG replied to Ebola57's topic in AutoIt General Help and Support
Unfortunately not... The "paste" lasts almost 90-100ms on my PC, while the AddPicture-Method runs under 20ms An other advantage of the AddPicture-Method is that you can set the size and rotation of the Picture. -
[SOLVED] Insert base64 image in XLS sheet
AndyG replied to Ebola57's topic in AutoIt General Help and Support
...now we are two at least 😄 -
[SOLVED] Insert base64 image in XLS sheet
AndyG replied to Ebola57's topic in AutoIt General Help and Support
Hi, one solution is to copy the base64 graphics into memory( aka clipboard) and insert it into the excel sheet #include-once #include <Excel.au3> #include <GDIPlus.au3> #include <Clipboard.au3> _GDIPlus_Startup() FileDelete(@ScriptDir & "\Test Graphic Out.xlsx") ;delete output file Global $Graphic = _Graphic_Base64_Generator("WS-C3750V2-48") ; <- My picture base64 encoded $hClipboard_Bitmap = _GDIPlus_BitmapCreateFromMemory($Graphic, True) ;make bitmap from base64 code $hHBmp_Clipboard = _WinAPI_CopyImage($hClipboard_Bitmap, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) ;make image from bitmap $ret = _WinAPI_Bitmap2Clipboard($hHBmp_Clipboard) ; copy image to clipboard Global $oExcel = _Excel_Open(False, False, False, True, True) Global $oWorkbook = _Excel_BookOpen($oExcel, @ScriptDir & "\Test Graphic.xlsx", True) $oWorkbook.Activesheet.Range("D8").activate ;position of picture $oWorkbook.Activesheet.paste ;paste image into excel sheet _Excel_BookSaveAs($oWorkbook, @ScriptDir & "\Test Graphic Out.xlsx", Default, True) _Excel_BookClose($oWorkbook, True) _Excel_Close($oExcel, False, True) ShellExecute(@ScriptDir & "\Test Graphic Out.xlsx") Func _Graphic_Base64_Generator($sGraphic_Name, $bSaveBinary = False, $sSavePath = @ScriptDir) Local $sGraphic_Raw = "" Switch $sGraphic_Name Case "WS-C3750V2-48" $sGraphic_Raw &= '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' $sGraphic_Raw &= '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' $sGraphic_Raw &= 'teXLkuQ0un/yW6REmkbrCzAJ6rTWKrexv5QaJf65bolGl6j5QZKrhKa2lnTjq2F/eKGey6Gcr4xmU4tqXO30gV+mRO1rl+X20se23rHEKkSjMKheXZKcdRy6vaJiTznSqjBykgCzYm28CqRMpiKvQdvCKTNWV5zlGAAOO2x7IqWWW4aVLDhyvS3pEtnkuswviwUAgD8XZ7RT3SY2omWpj0j1+cVPqv8AwWJNHMpmd6ZRKJR9jjt5QkyY7sqvlYtfxj43ChO/7yIx+yEKW7C/8RinCEUDwV7fpBCcGRAfBWt+kFxwdA7drBtz7QJh4OuY7Gz3HtCl+Dq+O4u/Z7RjM4Rmvk0y/wCkY/ZJxta2r4RhI4UZSfhWZ/EYz+Fmavk0z+Ix+ymxta2r4QFThJRR2BZtobDhBTLc4ze2DMHCG1DsW1dzCueEMXXutq7iAJnCGcDezTLwVbhbsp7QZnbAVeFOFGwAmwRT8KMoHwWZaCk7hrTEPapmQqpwp1A7As3sjGXwgy1veyzLQzrwhg7d5hN3MCb9kHUAsH1d4XPg5fHcZTL2jGZwguvk028Y/ZLY2tbV8ICpwlkUdgWbaMpPCNJu26zIEuZw13QeBmwL8LmuBsFaoJC+g8IMtuHuU7Lan8QLcMmhfwcwcfp2QqJw9lRRYATOz2idXy8ZCs+ODG/Yoj//xAAjEAACAgICAwEBAQEBAAAAAAABEQAhMUFRYXGBkaHB0bHw/9oACAEBAAE/IXyblEJnTj9ErYaEJCLyTBzTOrhinbNViBCScDiHZthA0oQh3CW3GoOkE4iIjgtLl3FokuUYwrb8iY0AUeX0gREYbP8Aeq3HC1WorW2xqo02CBimRxBq4CndzxD14gzODBizZu9CJMiuvSN6xcXRBYsQT/VXB2MlwdqMwZcJk4mKZfGYFdK6f2p3mHfkqoDRm+dTDtOBHJfDqAzAJjAyeA4Az+s2ZBAwv2IjotI5PhxEFCGY0MHy7glZpsB5Uccwqp7YIDKs/wDEDEUFqDfDocwMhGNA63LvnEDDMYGhVnOBqos4CULllsBi5Rj10mnD2q5SDMGWcxb5YMMHXJf/AEfsvhoMBFUcQl5Eh+o4JUXXR45uKwjeHS8Y7abFp+ZT8kf+jvwYZUqyMc+TBxiX6RHBKoDJF4Gr/dMm4MHEQPx3f1EXgJROmTpAews72OLquMajvrhQJgcnWIFskD6NDyhY9ZIqmx4VjEWpmC8j/pmLCBywZLeDB12VtDADLADHQjMdnMqZ+FtzY+fsCQ75Ue4VWKLJJbJ0iuEnBPrJx1H9VtHPddc5hJFLLg2sbcxDCiicXMWy7RyMfoybFQhCCjcgNlJxpRcLA5bN+RwdacKDfN8RV4z5BQEDfzEbXygJCaOvWBD2aIcYHHEuAuQgbNg8olrwCVEh1rSsQTnzYcQfpbcbiw2y3f1CvkQFDsNC/ZThYx6olmUQtx/WYgACQYfSBYooNCmeV/I02Nibig7f+QuESIy0TouIDuKFDn0r8H98GELAaRbbtGG4lBiAzyLhyrpVMd8je74hLZyEH8J8SiscjRxB+RjcNeB3BKHOk8wOQxAocL+xBhB+nMF9o35MpUrpgK/2OStR4JHVyiChzHAMWUI++8MmSwxCFRWVHOPipBSGAWR9rGoiikYSzPQVFFEYLA/xB5hJKagxziUExOKRZ0dTDQ1UqYcgY8rWkahtELj+BQx4aOiajwyRpJyJchH3iL8CRXTA4IeIGwBS0AbsfEFEBEqKXoiXWAHAuniL5W5HUHdjCqU6U+NQV/sKJwIHHI6rXKpAxEgC2ov7VMiJDFj7Lbh7B4WCoy1LkgHQRf5L+RRojBbIhQK6klMoySLaj/c5qoOCGC8RX7IDXCdB8ltqFIyprUNj1+xdx6OGXx2YXMghERHHTqBuAwADxpDQsZBAnmMFtJHlOUJoYkkjgGChMKnLcjSFop7Ko+jD7Y+H6JY6llSaYAhZoZujL/UX5666JY6l' $sGraphic_Raw &= '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' $sGraphic_Raw &= 'H1XD6X8tf8+cZQTcW8h/p1X6AyRzWLPmg+7wCBGinREUCHQrA5Zo4Mclr5rWVTeccOV5ekFX8MBvFeD0tkWkLJEEjrF7z5ZSl9CbW3hHMItM0sp0mRCHIhYB4BWKaw1H7vZfkouERfbTdaXj0EDOimtETfqnCg3zkxs1oNq7OOphOhyD45H8F6L1jbAJOIdIVBd5eIdLC5RGzhuDnTSlTrkHAFQMTOVqWhL+ghYMUe3zqtS+yFhFP7A2TeTWeDrVQ+ig79vQQlXpltcQF4BDrqxxiTYCGPPX3lQRdUGMhfThHh1IgeVAI2MK3EnGubC5WgBb+n3jPlA7SWkLoGgTr1dBwlGqoFE1Vd5JKp3SDosK/kM49w3WLAOLQfo94PMsiXpdYLorc4o4YwxhrnqKGp3ry54L0kVQmDHh8aaUaTARHmUnzlQssPif0YLRDHB4qDigaJa2EE8fes5M/ASBpKhVa6+Bsu4RkrKwRNF+9+pOHCiEqauRdb+Wv+XTJ+uE2z+58PeFMlSHx+aR+ae9eQYCtc0BGcDfuU/kzzQv8LxU0w2asmqUf4PsQ2a94uGkL+PeZ+qymR+gP/vK3WcIwX2MT9Z84foqs4BE2l/EeAyzJf8ANWqf7S5yHC1xsKxRUfN/MW6QY3Cfs38gJ7zA2DhLJiJOGRl6U5ZUJeUY91AWZi7Mkl63xTV7594SMSUxsmRO+ciII3V2UII/feUG0ACDkYq/x4eTkiwS2qFPWn77yPZUHw0go/GGXbqSDFCP7a/Rc6MmofOkAhOCx7x9da6ASITdL/i6GuJsKtCJX+/x842HRrsEuiLie8DlRCdVR91fPeN08LEyJ6Af7nC7kolYmR1n0R56H9iufQqP/PH0WdSgJLFT5r8xQlfz24qcpqA+8psEkY7TQofPnYOg2kFQq89PNs4nncAE0qaKTP7ybfgbGTS0EL9FHs/RbUAcAAMId75zcXABf62YkQ694fhjKylYLv79bwYIADWCAixihRlf3nFEKPDZl/pnZjW3DuA/+Oy5UlCUBFmX3giVIIf7fB7fOu4NMo/SDXBmvUZhPEvXTDSOHI7EqUNFQKO7yg7CaXEvHGfE4aRAqYVIEBVYYq8fXUGtCphwMfEzoILxiynyYz45kkKE1qgAbud7QGp7vAK113XodAtgA8NTDFmHGU6LIfnt6fOHFXOikGLFL7vFJQHwGgGj4e9eMusOQHhMhnMRYHglAgVokWHPR4CbkRPQnzx/O/h08BgIB/Dk9cZvIeAsAvuHf63Dlci/9dYnatGkeRrgzXqP7pWHqaw03DmwKJVDRQRbyC+hZolomMnnW8+rVtYACrc4F8U6RJlSH1rvBnAkghBu3F96w1T6QhHAAkgTzOAGcDQkMr4cdKd2QRQkLVv0r7vC39Cx4HfSzgjQgG/53//Z' EndSwitch Return Binary(_Graphic_WinAPI_Base64Decode($sGraphic_Raw)) EndFunc ;==>_Graphic_Base64_Generator Func _Graphic_WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_Graphic_WinAPI_Base64Decode Func _WinAPI_Bitmap2Clipboard($hHBitmap) If Not _ClipBoard_Open(0) Then Return 1 If Not _ClipBoard_Empty() Then Return 2 Local Const $hCP = _ClipBoard_SetDataEx($hHBitmap, $CF_BITMAP) If Not $hCP Or @error Then Return 3 _ClipBoard_Close() Return 0 EndFunc ;==>_WinAPI_Bitmap2Clipboard -
How To Convert DLLs into an AutoIT UDF?
AndyG replied to noellarkin's topic in AutoIt General Help and Support
As I mentioned, I had a short look at the source. As good as none dokumentation, the source of Actiona is straight C++ based on the QT-Framework. All parameters which goes in and come out of methods/functions are going through the QT. I am experienced with DLL (I did a quick look at this with IDA also) and I would trust myself to use a function of an Actiona-DLL but at what price?! Definetely you have to complete install Actiona to use one/some of the functions! And even then it would take much longer and would be more complicated than writing this function from scratch. An other idea could be to automate Actiona with an AutoIt-Script....🙄😱 @noellarkin, I would like to see an example or more of the images you are having trouble finding. -
How To Convert DLLs into an AutoIT UDF?
AndyG replied to noellarkin's topic in AutoIt General Help and Support
First I have to say, I am not a C/C++ Programmer, but after a quick look at the code in the git repository I noticed that Actiona uses OpenCV, especially the function matchTemplate (to find a image within an image) with various methods described here. AFAIK there is an OpenCV-UDF in AutoIt, which i would prefer rather than using lots of interdependent dll´s of a 3rd party program. -
In Assembler, "Loop unrolling" is (should be) very common to solve the "problem" with loops. So if you don´t want to use some of the Bit Twiddling Hacks mentioned by funkey, unroll your "bad" loop. Functions to reverse bits in Byte, Word, Dword Func _BitreverseByte($byte) ;reverses bits in the lower 8 bits of $byte Return BitOR( _ ;add all shifted bits together BitShift(BitAND($byte, 0x01), -7), _ ;Bit 0 to bit 7 BitShift(BitAND($byte, 0x02), -5), _ ;Bit 1 to bit 6 BitShift(BitAND($byte, 0x04), -3), _ ;Bit 2 to bit 5 BitShift(BitAND($byte, 0x08), -1), _ ;Bit 3 to bit 4 BitShift(BitAND($byte, 0x10), 1), _ ;Bit 4 to bit 3 BitShift(BitAND($byte, 0x20), 3), _ ;Bit 5 to bit 2 BitShift(BitAND($byte, 0x40), 5), _ ;Bit 6 to bit 1 BitShift(BitAND($byte, 0x80), 7)) ;Bit 7 to bit 0 EndFunc ;==>_BitreverseByte Func _bitreverseWord($word) ;reverses bits in the lower 16 bits of $byte Return BitOR( _ _BitreverseByte(BitShift($word, 8)), _ ;reverses upper 8 bits and shift to lower 8 bits BitShift(_BitreverseByte($word), -8)) ;reverses lower 8 bits and shift to higher 8 Bits EndFunc ;==>_bitreverseWord Func _bitreverseDword($dword) Return BitOR( _ _BitreverseByte(BitShift($dword, 24)), _ ;reverses upper 8 bits and shift to lower 8 bits BitShift(_BitreverseByte(BitShift($dword, 16)), -8), _ ; BitShift(_BitreverseByte(BitShift($dword, 08)), -16), _ ; BitShift(_BitreverseByte(BitShift($dword, 00)), -24)) ;reverses lower 8 bits and shift to higher 8 Bits EndFunc ;==>_bitreverseDword But i think these functions are not relating to For example 111, 101, 100111001, are palindromes which can not be calculated with functions having a restriction to the length of byte/word/dword. The question is, are leading zeroes (up to a given length of the whole "bitstring") also allowed, so that 001100 or 0111011101110 or 000010000 are palindromes too? If only palindromes are allowed with a leading 1, only odd numbers are in the value area . Global $a_[256], $b_[256], $c_[11111112] ;only to show the binarystring _DecToBin_Startup() ;only to show the binarystring For $i = 1 To 50050 step 2 If _isbitpalindrome($i) Then ConsoleWrite($i & " " & _DecToBin($i) & @CRLF) Next Func _isbitpalindrome($uint) ;returns 1 if uint is bitpalindrome Local $reversed = 0 Local $i = $uint While $i > 0 ;until all bits are shifted $reversed = BitOR(BitShift($reversed, -1), BitAND($i, 1)) ;shift LSB of $i into $reversed $i = BitShift($i, 1) ;next bit of $i WEnd Return ($reversed = $uint) ? 1 : 0 EndFunc ;==>_isbitpalindrome ;functions by mars ;https://autoit.de/thread/28809-suche-schnelle-funktion-zum-umrechnen-ins-dual-oder-hexadezimalsystem/?pageNo=1 Func _BinToDec($bin) Local $dec = 0, $array = StringSplit($bin, "") For $i = $array[0] To 1 Step -1 If $array[$i] = "1" Then $dec += 2 ^ ($array[0] - $i) Next Return $dec EndFunc ;==>_BinToDec ; <Func>--------------------------------------------------| ; Ermittelt eine Dualzahl (0101) aus einer Dezimalzahl | ; Die Dezimalzahl muss kleiner als 2^31 sein | ; --------------------------------------------------------| Func _DecToBin($d) Return $d < 256 ? $a_[$d] : $d < 65536 ? $a_[$d / 256] & $b_[BitAND($d, 255)] : $d < 16777216 ? $a_[$d / 65536] & $b_[BitAND($d / 256, 255)] & $b_[BitAND($d, 255)] : $a_[BitShift($d, 24)] & $b_[BitAND($d / 65536, 255)] & $b_[BitAND($d / 256, 255)] & $b_[BitAND($d, 255)] EndFunc ;==>_DecToBin ; <Func>--------------------------------------------------| ; Initialisiert die DecToBin UDF | ; --------------------------------------------------------| Func _DecToBin_Startup() Local $t = DllStructCreate('char[64]'), $p = _ DllStructGetPtr($t), $hDll = DllOpen('msvcrt.dll') For $i = 0 To 255 Step 1 DllCall($hDll, 'ptr:cdecl', '_i64toa', 'int64', _ $i, 'ptr', $p, 'int', 2) $a_[$i] = DllStructGetData($t, 1) $b_[$i] = StringRight('0000000' & $a_[$i], 8) $c_[$a_[$i]] = $i Next DllClose($hDll) EndFunc ;==>_DecToBin_Startup //EDIT got faster function _isbitpalindrome() and from the "old" one _reversebits() Func _isbitpalindrome($uint) ;returns 1 if uint is bitpalindrome Local $msb, $lsb For $msb = 31 To 0 Step -1 ;get position of msb from 31 to 0 If BitAND($uint, BitShift(1, -$msb)) Then ExitLoop Next While $lsb < $msb ;compare 2 bits If (BitAND($uint, BitShift(1, -$lsb)) ? 1 : 0) <> (BitAND($uint, BitShift(1, -$msb)) ? 1 : 0) Then Return 0 ;the 2 bits are not equal ;bits are equal, compare next 2 bits $lsb = $lsb + 1 ;bitposition $msb = $msb - 1 ;bitposition WEnd Return 1 EndFunc ;==>_isbitpalindrome Func _reversebits($uint) ;reverses the bits of a given uint Local $reversed = 0 While $uint > 0 ;until all bits are shifted $reversed = BitOR(BitShift($reversed, -1), BitAND($uint, 1)) ;shift LSB of $uint into $reversed $uint = BitShift($uint, 1) ;next bit of $uint WEnd Return $reversed EndFunc ;==>_reversebits
-
Because it´s no "ASM" code, it can´t be "easily" assembled (by i.e. FASM/MASM) and converted to AutoIt. AFAIK the code is a (part of a) CheatEngine Script...and of cause could be transformed to AutoIt with some lines of code. That requires the knowledge of some details of the program the call is pointing to.....but the OP/TS mentioned All said.
-
NO, definitely NOT! I downloaded and unzipped the File without any trouble!
-
Solving a (solved) problem with a (not really suitable) programming language is something "for fun". But to solve a problem with an unusual approach is exciting and "expands the horizon". Thank you for that! OT: Nowadays, working with Terabyte-sized programming languages to solve the simplest problems with Titanic-sized programs running on gigaherz-powered, kilowatts burning Multicore-Computers, is NORMAL! Why? Because we can! Solving a Sudoku-puzzle is possible with a 62 BYTES (yes Bytes) sized program within Milliseconds. No compiler is necessary, no frameworks, no libraries, no overpowered Hardware. Just to mention. Solving a problem definitely does not depend on modern tools. And Brain rulez!😉
-
;create struct $struct =dllstructcreate("int;float[4];dword") ;fill struct with data dllstructsetdata($struct,1,123456);int dllstructsetdata($struct,2,4.80114160043301e+030,1);float dllstructsetdata($struct,2,3.68584191575527e+024,2);float dllstructsetdata($struct,2,7.71403089381636e+031,3);float dllstructsetdata($struct,2,8.24605444209785e-019,4);float dllstructsetdata($struct,3,0xDEADBEEF);dword ;read some data from struct at offset 4 $struct2=dllstructcreate("char[16]",dllstructgetptr($struct)+4) msgbox(0,":o)",dllstructgetdata($struct2,1))