Bit by Bit compare percentage

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Jento
Posts: 6
Joined: 13 Oct 2021, 12:38

Bit by Bit compare percentage

24 Oct 2021, 07:46

Hi, could you help me or if that script exist point me to it? I need to compare 2 strings of bits for ex:
arg1: 100101011010110
arg2: 100010111010010

First to first, second to second...etc.
To tell me how much bits aren't the same- so then i can tell to calculate percentage of bits that don't match
My idea is to tell arg1, arg2 and the string length to compare and then to give percentage of incorrect bits.
And in the last part i can give threshold- if it reaches for ex. 20% then perform something.
User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Bit by Bit compare percentage

24 Oct 2021, 09:34

Code: Select all

arg1 = 100101011010110
arg2 = 100010111010010
same := 0
Loop, Parse, arg1
 same += A_LoopField = SubStr(arg2, A_Index, 1)
MsgBox, 64, Matched, % Round(100 * same / StrLen(arg1)) "%"
Or:

Code: Select all

arg1 = 100101011010110
arg2 = 100010111010010
MsgBox, 64, Matched, % same(arg1, arg2, 15) "%"

same(arg1, arg2, len := "") {
 Loop, % len := len ? len : StrLen(arg1)
  same += SubStr(arg1, A_Index, 1) = SubStr(arg2, A_Index, 1)
 Return Round(100 * same / len)
}
Or:

Code: Select all

arg1 = 100101011010110
arg2 = 100010111010010
MsgBox, 64, Different, % different(arg1, arg2, 15) "%"

different(arg1, arg2, len := "") {
 Loop, % len := len ? len : Max(StrLen(arg1), StrLen(arg2))
  dif += SubStr(arg1, A_Index, 1) != SubStr(arg2, A_Index, 1)
 Return Round(100 * dif / len)
}
Using math is another approach. Since these scripts start to compare on the left end of the string, they are working with strings rather than numbers.
Jento
Posts: 6
Joined: 13 Oct 2021, 12:38

Re: Bit by Bit compare percentage

24 Oct 2021, 20:11

Sincerely Thank You, you've seriously helped me.
I tried (since you replied) to implement this code, but after correcting many mistakes that i made, i just don't see what else is wrong.
Im trying to exchange "RtlCompareMemory" for Yours "different" function in ScrCmp() but i just don't see where else i made mistakes- my lack of knowledge won't let me go further.

This code:

Code: Select all

 DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)
      Count := ( (Byte := DllCall("ntdll.dll\RtlCompareMemory", "Ptr",pBits, "Ptr",pBits+Bytes, "Ptr",Bytes) ) != Bytes )
               ? (Count + 1) : 0
      Sleep % (Count ? Sleep[2] : Sleep[1])
I've changed into this code:

Code: Select all

different(arg1, arg2, len := "") {
	dif:=0
 Loop, % len := len ? len : Max(StrLen(arg1), StrLen(arg2))
  dif += SubStr(arg1, A_Index, 1) != SubStr(arg2, A_Index, 1)
 Return Round(100 * dif / len)
}
;==================================================
 DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)
	Diff:= different(NumGet(pBits, 0, "Ptr"), NumGet(pBits+Bytes, 0, "Ptr"), NumGet(Bytes, 0, "Ptr"))
      Count := (Diff > 20) ? (Count + 1) : 0

      Sleep % (Count ? Sleep[2] : Sleep[1])

From this function(i deleted part where it shows coordinates):

Code: Select all

ScrCmp( X, Y, W, H, Hwnd:=0x0, Sleep* )  {                                        ; v0.66 By SKAN on D3B3/D3B6 @ tiny.cc/scrcmp
Local
Global A_Args
  Sleep[1] := Sleep[1]="" ? 100 : Format("{:d}", Sleep[1])
  Sleep[2] := Sleep[2]="" ? 100 : Format("{:d}", Sleep[2])

  VarSetCapacity(BITMAPINFO, 40, 0)
  NumPut(32, NumPut(1, NumPut(0-H*2, NumPut(W, NumPut(40,BITMAPINFO,"Int"),"Int"),"Int"),"Short"),"Short")

  hBM := DllCall("Gdi32.dll\CreateDIBSection", "Ptr",0, "Ptr",&BITMAPINFO, "Int",0, "PtrP",pBits := 0, "Ptr",0, "Int",0, "Ptr")
  sDC := DllCall("User32.dll\GetDC", "Ptr",(Hwnd := WinExist("ahk_id" . Hwnd)), "Ptr")
  mDC := DllCall("Gdi32.dll\CreateCompatibleDC", "Ptr",sDC, "Ptr")
  DllCall("Gdi32.dll\SaveDC", "Ptr",mDC)
  DllCall("Gdi32.dll\SelectObject", "Ptr",mDC, "Ptr",hBM)
  DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",H, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)

  A_Args.ScrCmp := {"Wait": 1},   Bytes := W*H*4,  Count := 0
  hMod := DllCall("Kernel32.dll\LoadLibrary", "Str","ntdll.dll", "Ptr")
  While ( A_Args.ScrCmp.Wait && (Count<2) )
  {
      DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)
      Count := ( (Byte := DllCall("ntdll.dll\RtlCompareMemory", "Ptr",pBits, "Ptr",pBits+Bytes, "Ptr",Bytes) ) != Bytes )
               ? (Count + 1) : 0
      Sleep % (Count ? Sleep[2] : Sleep[1])
  } 
  DllCall("Kernel32.dll\FreeLibrary", "Ptr",hMod)

  If (Wait := A_Args.ScrCmp.Wait)
      A_Args.ScrCmp := { "Wait":0 }
  DllCall("Gdi32.dll\RestoreDC", "Ptr",mDC, "Int",-1)
  DllCall("Gdi32.dll\DeleteDC", "Ptr",mDC)
  DllCall("User32.dll\ReleaseDC", "Ptr",Hwnd, "Ptr",sDC)
  DllCall("Gdi32.dll\DeleteObject", "Ptr",hBM)
Return ( !!Wait )
viewtopic.php?t=82812
User avatar
mikeyww
Posts: 26936
Joined: 09 Sep 2014, 18:38

Re: Bit by Bit compare percentage

25 Oct 2021, 05:37

When I tried your DLL call, the values were null. I don't know what these steps should do, but I would debug that first. I see that several variables are undefined here.

Code: Select all

DllCall("Gdi32.dll\BitBlt", "Ptr",mDC, "Int",0, "Int",0, "Int",W, "Int",H, "Ptr",sDC, "Int",X, "Int",Y, "Int",0x40CC0020)
a := NumGet(pBits, 0, "Ptr")
b := NumGet(pBits+Bytes, 0, "Ptr")
c := NumGet(Bytes, 0, "Ptr")
MsgBox, #%a%# #%b%# #%c%#
image211025-0637-001.png
Output
image211025-0637-001.png (5.52 KiB) Viewed 377 times

It appears that you have problems with other parts of your script, rather than the part that compares strings. I would probably try to simplify your approach. When you call a function, variables defined inside the function are local by default.
just me
Posts: 9458
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Bit by Bit compare percentage

25 Oct 2021, 06:11

@SKAN's SrcCmp() function does not compare strings. RtlCompareMemory() is used to compare binary contents (bitmaps) on byte level. It doesn't compare/count single bits.

Your attempt does not create 'strings of bits', so @mikeyww's function cannot be used.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: OrangeCat and 150 guests