MCode from 32bit to 64bit Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Archandrion
Posts: 31
Joined: 26 May 2018, 22:23

MCode from 32bit to 64bit

24 Jun 2018, 13:05

I have found out that Mcode in the Gdip_FilterColor() function below appears to have been compiled for the 32bit version of Autohotkey. Could anyone assist me in converting it to run on the 64bit version. The source code can be found at https://pastebin.com/vFgELSEi but I was unsuccessful in using the MCode generator at https://github.com/joedf/MCode4GCC to create viable code. It did spit out an MCode but just replacing that in the function did not work.

Code: Select all

#include %A_ScriptDir%
#Include Gdip_All.ahk

InputFile := "ColorReplaced.png"
OutputFile := "ColorReplaced2.png"

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(InputFile)
E := Gdip_FilterColor(pBitmap, 0xFFC0C0C0, 0xFFFFFFFF, 100)
Gdip_SaveBitmapToFile(pBitmap, OutputFile)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

Gdip_FilterColor(pBitmap, Color, ReplaceColor, Variation=0)
{
	static _FilterColor
	if !_FilterColor
	{
		MCode_FilterColor := "83EC288B44243C8BC8C1E918894C243C8BC8C1E91081E1FF000000894C240C0FB6CC25FF000000894C2410894424148B442440"
		. "8BC8C1E918894C24188BC80FB6D425FF000000C1E910894424248B44243481E1FF00000085C0894C241C895424200F8E020100008B54242C5355568B7"
		. "4245033DB578B7C2440895C241489442418B90100000085FF0F8EC10000008D4A028D040B8BDA2BD983C303895C24508BDA2BD983C301895C24442BD1"
		. "897C24108B5C24448B4C24500FB62C030FB60C018B5C244C0FB63803DE3BCB7F688B5C244C2BDE3BCB7C5E8B4C241C8D1C313BFB7F532BCE3BF97C4D8"
		. "B4C24208D3C313BEF7F422BCE3BE97C3C8B7C24240FB60C028D1C373BCB7F2D2BFE3BCF7C270FB64C24288B7C2450880C070FB64C242C8B7C24448808"
		. "0FB64C2430880C070FB64C2434880C02B90100000083C004294C24100F8569FFFFFF8B7C24408B54243C8B5C2414035C2448294C2418895C24140F852"
		. "1FFFFFF5F5E5D5B33C083C428C3"
		
		VarSetCapacity(_FilterColor, StrLen(MCode_FilterColor)//2)
		Loop % StrLen(MCode_FilterColor)//2	  ;%
			NumPut("0x" SubStr(MCode_FilterColor, (2*A_Index)-1, 2), _FilterColor, A_Index-1, "char")
	}
	
	Variation := (Variation > 255) ? 255 : (Variation < 0) ? 0 : Variation
	Gdip_GetImageDimensions(pBitmap, w, h)
	E1 := Gdip_LockBits(pBitmap, 0, 0, w, h, Stride1, Scan01, BitmapData1)
	E := DllCall(&_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -1 : E
}

And below is the MCode that MCode4GCC generated.

Code: Select all

"2,x86:QVdBVkFVQVRVV1ZTSIPsOIuEJKgAAAAx7UmJz0SJhCSQAAAARIuEJKAAAABEiYwk"
    . "mAAAAESNNJUAAAAAicGJRCQsi4QksAAAAInPQYnKRYnBwe8YRInGQYHhAAD/AIl8"
    . "JCAPtv2LjCSQAAAAQYHiAAD/AEyJw8HuGEHB6hBBwekQiXwkKIXJD7bfRQ+2wESJ"
    . "VCQkvwMAAAAPjuUAAACNDAMpw0WNJAGJXCQUQY0cAEEpwUEpwESNHAaJTCQQKcZE"
    . "iUwkDIlcJBhEiUQkHEyJ+YXSRo0MN4n4D46OAAAAZpBBicCNWP1JAchFD7YQRTna"
    . "d25BOfJyaUSNaP9JAc1FD7ZVAEU54ndYRDtUJAxyUUSNeP5JAc9FD7YXRDtUJBB3"
    . "P0Q7VCQUcjhBidpJAcpBD7YaO1wkGHcoO1wkHHIiD7ZcJCBBiBgPtlwkJEGIXQAP"
    . "tlwkKEGIHw+2XCQsQYgakIPABEQ5yA+FdP///4PFAQO8JJgAAAA5rCSQAAAAD4VN"
    . "////McBIg8Q4W15fXUFcQV1BXkFfw5CQkJCQkJCQkJA="

The source code is:

Code: Select all

int Gdip_FilterColor(unsigned char * Bitmap, int w, int h, int Stride, unsigned int Color, unsigned int ReplaceColor, int v)
{
        unsigned int p, A1, R1, G1, B1, A2, R2, G2, B2, tA, tR, tG, tB;
 
        A1 = (Color & 0xff000000) >> 24;
        R1 = (Color & 0x00ff0000) >> 16;
        G1 = (Color & 0x0000ff00) >> 8;
        B1 = Color & 0x000000ff;
 
        A2 = (ReplaceColor & 0xff000000) >> 24;
        R2 = (ReplaceColor & 0x00ff0000) >> 16;
        G2 = (ReplaceColor & 0x0000ff00) >> 8;
        B2 = ReplaceColor & 0x000000ff;
 
        for (int y = 0; y < h; ++y)
        {
                for (int x = 0; x < w; ++x)
                {
                        p = (4*x)+(y*Stride);
 
                        tA = Bitmap[3+p];
                        tR = Bitmap[2+p];
                        tG = Bitmap[1+p];
                        tB = Bitmap[p];
                       
                        if ((tA <= A1+v && tA >= A1-v) && (tR <= R1+v && tR >= R1-v) && (tG <= G1+v && tG >= G1-v) && (tB <= B1+v && tB >= B1-v))
                        {
                                Bitmap[3+p] = A2;
                                Bitmap[2+p] = R2;
                                Bitmap[1+p] = G2;
                                Bitmap[p] = B2;
                        }
                       
                }
        }
        return 0;
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 13:16

Read the readme on joedf's github, you need to use the mcode function and make sure you use a 64 bit compiler, eg TDM-GCC.
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 13:31

2,x86:g+wYi0wkLIvBwegQUw+22IvBwegIVQ+26A+2wYlEJAhWi/GLTCQ8i8HB7hjB6BiJRCQUi8HB6BAPtsCJRCQYi8HB6AgPtsCJRCQcD7bBi0wkMIl0JBCJRCQghckPjr8AAACLRCQoi1QkQIPAAleLfCQwiUQkQIX/D46NAAAAjQwWiUwkPA+2cAE78Xdmi0wkFCvKO/FyWA+2MI0MEzvxd06LyyvKO/FyRg+2cP+NDCo78Xc7i80ryjvxcjOLTCQQD7Zw/gPKO/F3JYtMJBAryjvxchuLTCQYiEgBi0wkHIgIi0wkIIhI/4tMJCSISP6LTCQ8g8AEg+8BdYqLdCQUi0QkQIt8JDCLTCQ0A0QkOIPpAYlEJECJTCQ0D4VW////X15dM8Bbg8QYww==,x64:RIlMJCBEiUQkGFNVQVRBVUFWQVdIg+woRIuUJIAAAABFM+1Bi8JFD7b6wegQi+qLlCSIAAAARYvaRA+28EiL2UHB6xhBi8LB6AhED7bgi8LB6BiJRCQEi8LB6BAPtsCJRCQIi8LB6AgPtsCJRCQMD7bCiUQkEESJnCSAAAAARIksJEWFwA+OEgEAAIuEJJAAAACLTCRwSIl0JGBIiXwkIEUzwIXtD47YAAAAQYv1RY0UA0SLbCQERImUJIgAAABBD6/xDx9AAGYPH4QAAAAAAEaNDIZBjUkDD7YUGYv5QTvSD4eDAAAAQYvLK8g70XJ6QY1JAg+2FBlEi9lBjQwGO9F3X0GLzivIO9FyVkGNSQEPthQZRIvRQY0MBDvRdztBi8wryDvRcjJBD7YUGUGNDAc70XclQYvPK8g70XIci0wkCEGIDBuLTCQMQYgMGotMJBBBiAwZRIgsH0SLlCSIAAAARIucJIAAAABB/8BEO8UPjFr///9Eiywki0wkcESLTCR4Qf/FRIksJEQ76Q+MDf///0iLfCQgSIt0JGAzwEiDxChBX0FeQV1BXF1bww==
?
Archandrion
Posts: 31
Joined: 26 May 2018, 22:23

Re: MCode from 32bit to 64bit

24 Jun 2018, 13:48

Helgef wrote:Read the readme on joedf's github, you need to use the mcode function and make sure you use a 64 bit compiler, eg TDM-GCC.

That's precisely what I did or at least I think I did. I put the path to the g++.exe from tdm64-gcc-5.1.0-2 in the GCC compiler field in MCode4GCC. I set the Optimizations option to Speed(-Ofast) and clicked the Generate MCode button. The relevant code in the Gdip_FilterColor() function appears to be:

Code: Select all

	
	VarSetCapacity(_FilterColor, StrLen(MCode_FilterColor)//2)
		Loop % StrLen(MCode_FilterColor)//2	  ;%
			NumPut("0x" SubStr(MCode_FilterColor, (2*A_Index)-1, 2), _FilterColor, A_Index-1, "char")
And on joedf's github it says:

Code: Select all

Laszlo's version :
How to use it : http://www.autohotkey.com/board/topic/19483-machine-code-functions-bit-wizardry

MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
	VarSetCapacity(code,StrLen(hex)//2)
	Loop % StrLen(hex)//2
		NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}
So they seem to be in agreement.
Flipeador wrote:
2,x86:g+wYi0wkLIvBwegQUw+22IvBwegIVQ+26A+2wYlEJAhWi/GLTCQ8i8HB7hjB6BiJRCQUi8HB6BAPtsCJRCQYi8HB6AgPtsCJRCQcD7bBi0wkMIl0JBCJRCQghckPjr8AAACLRCQoi1QkQIPAAleLfCQwiUQkQIX/D46NAAAAjQwWiUwkPA+2cAE78Xdmi0wkFCvKO/FyWA+2MI0MEzvxd06LyyvKO/FyRg+2cP+NDCo78Xc7i80ryjvxcjOLTCQQD7Zw/gPKO/F3JYtMJBAryjvxchuLTCQYiEgBi0wkHIgIi0wkIIhI/4tMJCSISP6LTCQ8g8AEg+8BdYqLdCQUi0QkQIt8JDCLTCQ0A0QkOIPpAYlEJECJTCQ0D4VW////X15dM8Bbg8QYww==,x64:RIlMJCBEiUQkGFNVQVRBVUFWQVdIg+woRIuUJIAAAABFM+1Bi8JFD7b6wegQi+qLlCSIAAAARYvaRA+28EiL2UHB6xhBi8LB6AhED7bgi8LB6BiJRCQEi8LB6BAPtsCJRCQIi8LB6AgPtsCJRCQMD7bCiUQkEESJnCSAAAAARIksJEWFwA+OEgEAAIuEJJAAAACLTCRwSIl0JGBIiXwkIEUzwIXtD47YAAAAQYv1RY0UA0SLbCQERImUJIgAAABBD6/xDx9AAGYPH4QAAAAAAEaNDIZBjUkDD7YUGYv5QTvSD4eDAAAAQYvLK8g70XJ6QY1JAg+2FBlEi9lBjQwGO9F3X0GLzivIO9FyVkGNSQEPthQZRIvRQY0MBDvRdztBi8wryDvRcjJBD7YUGUGNDAc70XclQYvPK8g70XIci0wkCEGIDBuLTCQMQYgMGotMJBBBiAwZRIgsH0SLlCSIAAAARIucJIAAAABB/8BEO8UPjFr///9Eiywki0wkcESLTCR4Qf/FRIksJEQ76Q+MDf///0iLfCQgSIt0JGAzwEiDxChBX0FeQV1BXF1bww==
?
I am not sure about these. Should I only use the code after 64? I didn't want to just try using only a part of it as I'm not sure if it could cause serious errors.
Last edited by Archandrion on 24 Jun 2018, 13:57, edited 2 times in total.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 13:55

Try Bentschi's mcode function which you already read about in the readme ;)

Edit, hello Flipeador :wave:
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 14:23

I am not sure about these. Should I only use the code after 64? I didn't want to just try using only a part of it as I'm not sure if it could cause serious errors.
Read https://autohotkey.com/boards/viewtopic.php?f=7&t=32.

Code: Select all

MCode(mcode)
{
  static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
  if (c="x64")
    DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
    return p
  DllCall("GlobalFree", "ptr", p)
}
Simply pass the entire string to the MCode function.

@Helgef Hi! :wave:
Archandrion
Posts: 31
Joined: 26 May 2018, 22:23

Re: MCode from 32bit to 64bit

24 Jun 2018, 14:44

Flipeador wrote:
Simply pass the entire string to the MCode function.
I tried to pass the entire string to to the MCode function but it does not seem to work. This is the code I now have:

Code: Select all

#include %A_ScriptDir%
#Include Gdip_All.ahk

InputFile := "ColorReplaced.png"
OutputFile := "ColorReplaced2.png"

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(InputFile)
E := Gdip_FilterColor(pBitmap, 0xFFC0C0C0, 0xFFFFFFFF, 100)
Gdip_SaveBitmapToFile(pBitmap, OutputFile)
MsgBox Completed
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

Gdip_FilterColor(pBitmap, Color, ReplaceColor, Variation=0)
{
	static _FilterColor
	if !_FilterColor
	{
		MCode_FilterColor := "2,x86:g+wYi0wkLIvBwegQUw+22IvBwegIVQ+26A+2wYlEJAhWi/GLTCQ8i8HB7hjB6BiJRCQUi8HB6BAPtsCJRCQYi8HB6AgPtsCJ"
        . "RCQcD7bBi0wkMIl0JBCJRCQghckPjr8AAACLRCQoi1QkQIPAAleLfCQwiUQkQIX/D46NAAAAjQwWiUwkPA+2cAE78Xdmi0wkFCvKO/FyWA+2MI0MEzvxd06Ly"
        . "yvKO/FyRg+2cP+NDCo78Xc7i80ryjvxcjOLTCQQD7Zw/gPKO/F3JYtMJBAryjvxchuLTCQYiEgBi0wkHIgIi0wkIIhI/4tMJCSISP6LTCQ8g8AEg+8BdYqLdC"
        . "QUi0QkQIt8JDCLTCQ0A0QkOIPpAYlEJECJTCQ0D4VW////X15dM8Bbg8QYww==,x64:RIlMJCBEiUQkGFNVQVRBVUFWQVdIg+woRIuUJIAAAABFM+1Bi8JFD7"
        . "b6wegQi+qLlCSIAAAARYvaRA+28EiL2UHB6xhBi8LB6AhED7bgi8LB6BiJRCQEi8LB6BAPtsCJRCQIi8LB6AgPtsCJRCQMD7bCiUQkEESJnCSAAAAARIksJEW"
        . "FwA+OEgEAAIuEJJAAAACLTCRwSIl0JGBIiXwkIEUzwIXtD47YAAAAQYv1RY0UA0SLbCQERImUJIgAAABBD6/xDx9AAGYPH4QAAAAAAEaNDIZBjUkDD7YUGYv5"
        . "QTvSD4eDAAAAQYvLK8g70XJ6QY1JAg+2FBlEi9lBjQwGO9F3X0GLzivIO9FyVkGNSQEPthQZRIvRQY0MBDvRdztBi8wryDvRcjJBD7YUGUGNDAc70XclQYvPK"
        . "8g70XIci0wkCEGIDBuLTCQMQYgMGotMJBBBiAwZRIgsH0SLlCSIAAAARIucJIAAAABB/8BEO8UPjFr///9Eiywki0wkcESLTCR4Qf/FRIksJEQ76Q+MDf///0"
        . "iLfCQgSIt0JGAzwEiDxChBX0FeQV1BXF1bww=="
        
		
		_FilterColor := MCode(MCode_FilterColor)
	}
	
	Variation := (Variation > 255) ? 255 : (Variation < 0) ? 0 : Variation
	Gdip_GetImageDimensions(pBitmap, w, h)
	E1 := Gdip_LockBits(pBitmap, 0, 0, w, h, Stride1, Scan01, BitmapData1)
	E := DllCall(&_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -1 : E
}

MCode(mcode) {
	static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
	if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
		return
	if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
		return
	p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
	if (c="x64")
		DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
	if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
		return p
	DllCall("GlobalFree", "ptr", p)
}
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: MCode from 32bit to 64bit

24 Jun 2018, 14:47

You dont need to use E := DllCall(&_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation) anymore
You can now just use E := DllCall(_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation)
Recommends AHK Studio
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 14:49

.. and I think "uint", Scan01 should be "uptr", Scan01.
Archandrion
Posts: 31
Joined: 26 May 2018, 22:23

Re: MCode from 32bit to 64bit

24 Jun 2018, 15:40

nnnik wrote:You dont need to use E := DllCall(&_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation) anymore
You can now just use E := DllCall(_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation)
Flipeador wrote:.. and I think "uint", Scan01 should be "uptr", Scan01.
I tried just replacing it first with E := DllCall(_FilterColor, "uint", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation) and then when that did not work tried E := DllCall(_FilterColor, "uptr", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation) but it still does not appear to have made the color change to the image. The code I now have is:

Code: Select all

#include %A_ScriptDir%
#Include Gdip_All.ahk

InputFile := "ColorReplaced.png"
OutputFile := "ColorReplaced2.png"

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(InputFile)
E := Gdip_FilterColor(pBitmap, 0xFFC0C0C0, 0xFFFFFFFF, 100)
Gdip_SaveBitmapToFile(pBitmap, OutputFile)
MsgBox Completed
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

Gdip_FilterColor(pBitmap, Color, ReplaceColor, Variation=0)
{
	static _FilterColor
	if !_FilterColor
	{
		MCode_FilterColor := "2,x86:g+wYi0wkLIvBwegQUw+22IvBwegIVQ+26A+2wYlEJAhWi/GLTCQ8i8HB7hjB6BiJRCQUi8HB6BAPtsCJRCQYi8HB6AgPtsCJ"
        . "RCQcD7bBi0wkMIl0JBCJRCQghckPjr8AAACLRCQoi1QkQIPAAleLfCQwiUQkQIX/D46NAAAAjQwWiUwkPA+2cAE78Xdmi0wkFCvKO/FyWA+2MI0MEzvxd06Ly"
        . "yvKO/FyRg+2cP+NDCo78Xc7i80ryjvxcjOLTCQQD7Zw/gPKO/F3JYtMJBAryjvxchuLTCQYiEgBi0wkHIgIi0wkIIhI/4tMJCSISP6LTCQ8g8AEg+8BdYqLdC"
        . "QUi0QkQIt8JDCLTCQ0A0QkOIPpAYlEJECJTCQ0D4VW////X15dM8Bbg8QYww==,x64:RIlMJCBEiUQkGFNVQVRBVUFWQVdIg+woRIuUJIAAAABFM+1Bi8JFD7"
        . "b6wegQi+qLlCSIAAAARYvaRA+28EiL2UHB6xhBi8LB6AhED7bgi8LB6BiJRCQEi8LB6BAPtsCJRCQIi8LB6AgPtsCJRCQMD7bCiUQkEESJnCSAAAAARIksJEW"
        . "FwA+OEgEAAIuEJJAAAACLTCRwSIl0JGBIiXwkIEUzwIXtD47YAAAAQYv1RY0UA0SLbCQERImUJIgAAABBD6/xDx9AAGYPH4QAAAAAAEaNDIZBjUkDD7YUGYv5"
        . "QTvSD4eDAAAAQYvLK8g70XJ6QY1JAg+2FBlEi9lBjQwGO9F3X0GLzivIO9FyVkGNSQEPthQZRIvRQY0MBDvRdztBi8wryDvRcjJBD7YUGUGNDAc70XclQYvPK"
        . "8g70XIci0wkCEGIDBuLTCQMQYgMGotMJBBBiAwZRIgsH0SLlCSIAAAARIucJIAAAABB/8BEO8UPjFr///9Eiywki0wkcESLTCR4Qf/FRIksJEQ76Q+MDf///0"
        . "iLfCQgSIt0JGAzwEiDxChBX0FeQV1BXF1bww=="
        
		
		_FilterColor := MCode(MCode_FilterColor)
	}
	
	Variation := (Variation > 255) ? 255 : (Variation < 0) ? 0 : Variation
	Gdip_GetImageDimensions(pBitmap, w, h)
	E1 := Gdip_LockBits(pBitmap, 0, 0, w, h, Stride1, Scan01, BitmapData1)
	E := DllCall(_FilterColor, "uptr", Scan01, "int", w, "int", h, "int", Stride1, "uint", Color, "uint", ReplaceColor, "int", Variation)
	Gdip_UnlockBits(pBitmap, BitmapData1)
	return (E = "") ? -1 : E
}

MCode(mcode) {
	static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
	if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
		return
	if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
		return
	p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
	if (c="x64")
		DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
	if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
		return p
	DllCall("GlobalFree", "ptr", p)
}
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 18:25

Maybe the problem is the machine code, I have used VS Community 2017. Test with AHKU32 with the previous machine code.

Code: Select all

"2,x86:QVdBVkFVQVRVV1ZTSIPsOIuEJKgAAAAx7UmJz0SJhCSQAAAARIuEJKAAAABEiYwk"
    . "mAAAAESNNJUAAAAAicGJRCQsi4QksAAAAInPQYnKRYnBwe8YRInGQYHhAAD/AIl8"
    . "JCAPtv2LjCSQAAAAQYHiAAD/AEyJw8HuGEHB6hBBwekQiXwkKIXJD7bfRQ+2wESJ"
    . "VCQkvwMAAAAPjuUAAACNDAMpw0WNJAGJXCQUQY0cAEEpwUEpwESNHAaJTCQQKcZE"
    . "iUwkDIlcJBhEiUQkHEyJ+YXSRo0MN4n4D46OAAAAZpBBicCNWP1JAchFD7YQRTna"
    . "d25BOfJyaUSNaP9JAc1FD7ZVAEU54ndYRDtUJAxyUUSNeP5JAc9FD7YXRDtUJBB3"
    . "P0Q7VCQUcjhBidpJAcpBD7YaO1wkGHcoO1wkHHIiD7ZcJCBBiBgPtlwkJEGIXQAP"
    . "tlwkKEGIHw+2XCQsQYgakIPABEQ5yA+FdP///4PFAQO8JJgAAAA5rCSQAAAAD4VN"
    . "////McBIg8Q4W15fXUFcQV1BXkFfw5CQkJCQkJCQkJA="
It works?.
iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: MCode from 32bit to 64bit

24 Jun 2018, 23:55

Here's a code example from one of my projects you can imitate:

Code: Select all

         GaussianBlur(ByRef pBitmap, radius, opacity := 1) {
            static x86 := "
            (LTrim
            VYnlV1ZTg+xci0Uci30c2UUgx0WsAwAAAI1EAAGJRdiLRRAPr0UYicOJRdSLRRwP
            r/sPr0UYiX2ki30UiUWoi0UQjVf/i30YSA+vRRgDRQgPr9ONPL0SAAAAiUWci0Uc
            iX3Eg2XE8ECJVbCJRcCLRcSJZbToAAAAACnEi0XEiWXk6AAAAAApxItFxIllzOgA
            AAAAKcSLRaiJZcjHRdwAAAAAx0W8AAAAAIlF0ItFvDtFFA+NcAEAAItV3DHAi12c
            i3XQiVXgAdOLfQiLVdw7RRiNDDp9IQ+2FAGLTcyLfciJFIEPtgwDD69VwIkMh4tN
            5IkUgUDr0THSO1UcfBKLXdwDXQzHRbgAAAAAK13Q6yAxwDtFGH0Ni33kD7YcAQEc
            h0Dr7kIDTRjrz/9FuAN1GItF3CtF0AHwiceLRbg7RRx/LDHJO00YfeGLRQiLfcwB
            8A+2BAgrBI+LfeQDBI+ZiQSPjTwz933YiAQPQevWi0UIK0Xci03AAfCJRbiLXRCJ
            /itdHCt13AN14DnZfAgDdQwrdeDrSot1DDHbK3XcAf4DdeA7XRh9KItV4ItFuAHQ
            A1UID7YEGA+2FBop0ItV5AMEmokEmpn3fdiIBB5D69OLRRhBAUXg66OLRRhDAUXg
            O10QfTIxyTtNGH3ti33Ii0XgA0UID7YUCIsEjynQi1XkAwSKiQSKi1XgjTwWmfd9
            2IgED0Hr0ItF1P9FvAFF3AFF0OmE/v//i0Wkx0XcAAAAAMdFvAAAAACJRdCLRbAD
            RQyJRaCLRbw7RRAPjXABAACLTdwxwItdoIt10IlN4AHLi30Mi1XcO0UYjQw6fSEP
            thQBi33MD7YMA4kUh4t9yA+vVcCJDIeLTeSJFIFA69Ex0jtVHHwSi13cA10Ix0W4
            AAAAACtd0OsgMcA7RRh9DYt95A+2HAEBHIdA6+5CA03U68//RbgDddSLRdwrRdAB
            8InHi0W4O0UcfywxyTtNGH3hi0UMi33MAfAPtgQIKwSPi33kAwSPmYkEj408M/d9
            2IgED0Hr1otFDCtF3ItNwAHwiUW4i10Uif4rXRwrddwDdeA52XwIA3UIK3Xg60qL
            dQgx2yt13AH+A3XgO10YfSiLVeCLRbgB0ANVDA+2BBgPthQaKdCLVeQDBJqJBJqZ
            933YiAQeQ+vTi0XUQQFF4Ouji0XUQwFF4DtdFH0yMck7TRh97Yt9yItF4ANFDA+2
            FAiLBI+LfeQp0ItV4AMEj4kEj408Fpn3fdiIBA9B69CLRRj/RbwBRdwBRdDphP7/
            //9NrItltA+Fofz//9no3+l2PzHJMds7XRR9OotFGIt9CA+vwY1EBwMx/zt9EH0c
            D7Yw2cBHVtoMJFrZXeTzDyx15InyiBADRRjr30MDTRDrxd3Y6wLd2I1l9DHAW15f
            XcM=
            )"
            static x64 := "
            (LTrim
            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
            )"
            width := Gdip_GetImageWidth(pBitmap)
            height := Gdip_GetImageHeight(pBitmap)
            clone := Gdip_CloneBitmapArea(pBitmap, 0, 0, width, height)
            E1 := Gdip_LockBits(pBitmap, 0, 0, width, height, Stride1, Scan01, BitmapData1)
            E2 := Gdip_LockBits(clone, 0, 0, width, height, Stride2, Scan02, BitmapData2)

            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",0, "uint*",s, "ptr",0, "ptr",0)
            p := DllCall("GlobalAlloc", "uint",0, "ptr",s, "ptr")
            if (A_PtrSize == 8)
               DllCall("VirtualProtect", "ptr",p, "ptr",s, "uint",0x40, "uint*",op)
            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",p, "uint*",s, "ptr",0, "ptr",0)
            value := DllCall(p, "ptr",Scan01, "ptr",Scan02, "uint",width, "uint",height, "uint",4, "uint",radius, "float",opacity)
            DllCall("GlobalFree", "ptr", p)

            Gdip_UnlockBits(pBitmap, BitmapData1)
            Gdip_UnlockBits(clone, BitmapData2)
            Gdip_DisposeImage(clone)
            return value
         }
iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: MCode from 32bit to 64bit  Topic is solved

25 Jun 2018, 00:07

Code: Select all

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(InputFile)
Gdip_FilterColor(pBitmap, 0xFFC0C0C0, 0xFFFFFFFF, 100)
Gdip_SaveBitmapToFile(pBitmap, OutputFile)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

Gdip_FilterColor(ByRef pBitmap, Color, ReplaceColor, Variation:=0) {
            static x86 := "
            (LTrim
            QVdBVkFVQVRVV1ZTSIPsOIuEJKgAAAAx7UmJz0SJhCSQAAAARIuEJKAAAABEiYwk
            mAAAAESNNJUAAAAAicGJRCQsi4QksAAAAInPQYnKRYnBwe8YRInGQYHhAAD/AIl8
            JCAPtv2LjCSQAAAAQYHiAAD/AEyJw8HuGEHB6hBBwekQiXwkKIXJD7bfRQ+2wESJ
            VCQkvwMAAAAPjuUAAACNDAMpw0WNJAGJXCQUQY0cAEEpwUEpwESNHAaJTCQQKcZE
            iUwkDIlcJBhEiUQkHEyJ+YXSRo0MN4n4D46OAAAAZpBBicCNWP1JAchFD7YQRTna
            d25BOfJyaUSNaP9JAc1FD7ZVAEU54ndYRDtUJAxyUUSNeP5JAc9FD7YXRDtUJBB3
            P0Q7VCQUcjhBidpJAcpBD7YaO1wkGHcoO1wkHHIiD7ZcJCBBiBgPtlwkJEGIXQAP
            tlwkKEGIHw+2XCQsQYgakIPABEQ5yA+FdP///4PFAQO8JJgAAAA5rCSQAAAAD4VN
            ////McBIg8Q4W15fXUFcQV1BXkFfw5CQkJCQkJCQkJA=
            )"
            static x64 := "
            (LTrim
            QVdBVkFVQVRVV1ZTSIPsQIuEJLgAAABBideJVCQIi5QkqAAAAESJTCQQRIuMJLAA
            AABFicZEiUQkDEmJyonXQYnVD7begecAAP8ARInOTInJQYn4RInPgeYAAP8Awe8Y
            iXQkJEHB7RhBwegQiXwkLMFsJCQQD7b9QQ+28UWF9g+20ol8JDCJdCQ0D44PAQAA
            QY00AESJ/0EpwMHnAkWNZAUAQb4DAAAAiXwkFIk0JI08A400AinDKcJFMf9BKcVE
            iUQkBIl8JBiJXCQcTInRiXQkIIlUJChmDx+EAAAAAACLRCQIhcAPjp8AAACLRCQU
            QY00BkSJ8GYPH4QAAAAAAEGJw0SNUP9EjUj+SQHLRI1A/UEPthNJAcpJAclJAchB
            D7YaQQ+2OUEPtihEOeJ3UEQ56nJLOxwkd0Y7XCQEckA7fCQYdzo7fCQccjQ7bCQg
            dy47bCQocigPtnwkLEGIOw+2fCQkQYg6D7Z8JDBBiDkPtnwkNEGIOA8fhAAAAAAA
            g8AEOfAPhXX///9Bg8cBRAN0JBBEO3wkDA+FQf///zHASIPEQFteX11BXEFdQV5B
            X8M=
            )"
            Variation := (Variation > 255) ? 255 : (Variation < 0) ? 0 : Variation

            width := Gdip_GetImageWidth(pBitmap)
            height := Gdip_GetImageHeight(pBitmap)
            E1 := Gdip_LockBits(pBitmap, 0, 0, width, height, Stride1, Scan01, BitmapData1)

            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",0, "uint*",s, "ptr",0, "ptr",0) ; s stands for size. 
            p := DllCall("GlobalAlloc", "uint",0, "ptr",s, "ptr") ; p stands for pointer. 
            if (A_PtrSize == 8)
               DllCall("VirtualProtect", "ptr",p, "ptr",s, "uint",0x40, "uint*",op) ; op stands for Old Protect. 
            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",p, "uint*",s, "ptr",0, "ptr",0) ; loads binary to our pointer
            value := DllCall(p, "ptr",Scan01, "int",width, "int",height, "int",Stride1, "ptr",Color, "ptr",ReplaceColor, "int",Variation) ; call ur function.
            DllCall("GlobalFree", "ptr", p) ; free our pointer's allocated memory. 
            Gdip_UnlockBits(pBitmap, BitmapData1) ; un;lock your bitmap
            return value
}
untested.

For x64 code, use the MCode generator, by pointing it to "g++" from the x64 version found in win-builds. http://win-builds.org/doku.php Use the optimize for fast code/optimize for size options. Make sure you strip off the preceding x64/x86 characters, those are un-necessary in my version.
Archandrion
Posts: 31
Joined: 26 May 2018, 22:23

Re: MCode from 32bit to 64bit

25 Jun 2018, 12:45

iseahound wrote:

Code: Select all

pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmapFromFile(InputFile)
Gdip_FilterColor(pBitmap, 0xFFC0C0C0, 0xFFFFFFFF, 100)
Gdip_SaveBitmapToFile(pBitmap, OutputFile)
Gdip_DisposeImage(pBitmap)
Gdip_Shutdown(pToken)
return

Gdip_FilterColor(ByRef pBitmap, Color, ReplaceColor, Variation:=0) {
            static x86 := "
            (LTrim
            QVdBVkFVQVRVV1ZTSIPsOIuEJKgAAAAx7UmJz0SJhCSQAAAARIuEJKAAAABEiYwk
            mAAAAESNNJUAAAAAicGJRCQsi4QksAAAAInPQYnKRYnBwe8YRInGQYHhAAD/AIl8
            JCAPtv2LjCSQAAAAQYHiAAD/AEyJw8HuGEHB6hBBwekQiXwkKIXJD7bfRQ+2wESJ
            VCQkvwMAAAAPjuUAAACNDAMpw0WNJAGJXCQUQY0cAEEpwUEpwESNHAaJTCQQKcZE
            iUwkDIlcJBhEiUQkHEyJ+YXSRo0MN4n4D46OAAAAZpBBicCNWP1JAchFD7YQRTna
            d25BOfJyaUSNaP9JAc1FD7ZVAEU54ndYRDtUJAxyUUSNeP5JAc9FD7YXRDtUJBB3
            P0Q7VCQUcjhBidpJAcpBD7YaO1wkGHcoO1wkHHIiD7ZcJCBBiBgPtlwkJEGIXQAP
            tlwkKEGIHw+2XCQsQYgakIPABEQ5yA+FdP///4PFAQO8JJgAAAA5rCSQAAAAD4VN
            ////McBIg8Q4W15fXUFcQV1BXkFfw5CQkJCQkJCQkJA=
            )"
            static x64 := "
            (LTrim
            QVdBVkFVQVRVV1ZTSIPsQIuEJLgAAABBideJVCQIi5QkqAAAAESJTCQQRIuMJLAA
            AABFicZEiUQkDEmJyonXQYnVD7begecAAP8ARInOTInJQYn4RInPgeYAAP8Awe8Y
            iXQkJEHB7RhBwegQiXwkLMFsJCQQD7b9QQ+28UWF9g+20ol8JDCJdCQ0D44PAQAA
            QY00AESJ/0EpwMHnAkWNZAUAQb4DAAAAiXwkFIk0JI08A400AinDKcJFMf9BKcVE
            iUQkBIl8JBiJXCQcTInRiXQkIIlUJChmDx+EAAAAAACLRCQIhcAPjp8AAACLRCQU
            QY00BkSJ8GYPH4QAAAAAAEGJw0SNUP9EjUj+SQHLRI1A/UEPthNJAcpJAclJAchB
            D7YaQQ+2OUEPtihEOeJ3UEQ56nJLOxwkd0Y7XCQEckA7fCQYdzo7fCQccjQ7bCQg
            dy47bCQocigPtnwkLEGIOw+2fCQkQYg6D7Z8JDBBiDkPtnwkNEGIOA8fhAAAAAAA
            g8AEOfAPhXX///9Bg8cBRAN0JBBEO3wkDA+FQf///zHASIPEQFteX11BXEFdQV5B
            X8M=
            )"
            Variation := (Variation > 255) ? 255 : (Variation < 0) ? 0 : Variation

            width := Gdip_GetImageWidth(pBitmap)
            height := Gdip_GetImageHeight(pBitmap)
            E1 := Gdip_LockBits(pBitmap, 0, 0, width, height, Stride1, Scan01, BitmapData1)

            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",0, "uint*",s, "ptr",0, "ptr",0) ; s stands for size. 
            p := DllCall("GlobalAlloc", "uint",0, "ptr",s, "ptr") ; p stands for pointer. 
            if (A_PtrSize == 8)
               DllCall("VirtualProtect", "ptr",p, "ptr",s, "uint",0x40, "uint*",op) ; op stands for Old Protect. 
            DllCall("crypt32\CryptStringToBinary", "str",(A_PtrSize == 8) ? x64 : x86, "uint",0, "uint",0x1, "ptr",p, "uint*",s, "ptr",0, "ptr",0) ; loads binary to our pointer
            value := DllCall(p, "ptr",Scan01, "int",width, "int",height, "int",Stride1, "ptr",Color, "ptr",ReplaceColor, "int",Variation) ; call ur function.
            DllCall("GlobalFree", "ptr", p) ; free our pointer's allocated memory. 
            Gdip_UnlockBits(pBitmap, BitmapData1) ; un;lock your bitmap
            return value
}
untested.

For x64 code, use the MCode generator, by pointing it to "g++" from the x64 version found in win-builds. http://win-builds.org/doku.php Use the optimize for fast code/optimize for size options. Make sure you strip off the preceding x64/x86 characters, those are un-necessary in my version.
Thanks, that solved the issue.
User avatar
Xtra
Posts: 2744
Joined: 02 Oct 2015, 12:15

Re: MCode from 32bit to 64bit

01 Nov 2019, 12:09

Some notes after some testing.

Tics 32bit only function works.
@iseahound's function the 64bit works but 32bit does not work.

Using _FilterColor with or without "uptr" in Tics 32bit function does not work.

This is with Unicode 32 / 64 AHK.
iseahound
Posts: 1434
Joined: 13 Aug 2016, 21:04
Contact:

Re: MCode from 32bit to 64bit

22 Aug 2022, 10:41

Here's an updated version that properly works with 32-bit and 64-bits.

Code: Select all

Gdip_FilterColor(pBitmap, key, value, variation) {

   ; Get Bitmap width and height.
   DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap, "uint*", width:=0)
   DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap, "uint*", height:=0)

   ; Create a pixel buffer.
   VarSetCapacity(Rect, 16, 0)            ; sizeof(Rect) = 16
      NumPut(  width, Rect,  8,   "uint") ; Width
      NumPut( height, Rect, 12,   "uint") ; Height
   VarSetCapacity(BitmapData, 16+2*A_PtrSize, 0)   ; sizeof(BitmapData) = 24, 32
   DllCall("gdiplus\GdipBitmapLockBits"
            ,    "ptr", pBitmap
            ,    "ptr", &Rect
            ,   "uint", 3            ; ImageLockMode.ReadWrite
            ,    "int", 0x26200A     ; Format32bppArgb
            ,    "ptr", &BitmapData)
   Scan0 := NumGet(BitmapData, 16, "ptr")

   ; C source code - https://godbolt.org/z/3Gf341hsb
   static code := 0
   if !code {
      b64 := (A_PtrSize == 4)
         ? "VYnlVlNSikUQi3UIilUcik0gil0kiEX3ikUUiEX2ikUYiEX1O3UMcy2KRgI4RfdyIDpF9nIbikYBOEX1chM40HIPigY4wXIJONhyBYtFKIkGg8YE685YW15dww=="
         : "VlNEilQkOESKXCRAilwkSECKdCRQSInISDnQczGKSAJBOMhyI0Q4yXIeikgBQTjKchZEONlyEYoIOMtyC0A48XIGi0wkWIkISIPABOvKW17D"
      s64 := StrLen(RTrim(b64, "=")) * 3 // 4
      code := DllCall("GlobalAlloc", "uint", 0, "uptr", s64, "ptr")
      DllCall("crypt32\CryptStringToBinary", "str", b64, "uint", 0, "uint", 0x1, "ptr", code, "uint*", s64, "ptr", 0, "ptr", 0)
      DllCall("VirtualProtect", "ptr", code, "ptr", s64, "uint", 0x40, "uint*", op:=0)
   }

   v := abs(variation)
   r := ((key & 0xFF0000) >> 16)
   g := ((key & 0xFF00) >> 8)
   b := ((key & 0xFF))

   ; When doing pointer arithmetic, *Scan0 + 1 is actually adding 4 bytes.
   DllCall(code, "ptr", Scan0, "ptr", Scan0 + 4*width*height
            , "uchar", min(r+v, 255)
            , "uchar", max(r-v, 0)
            , "uchar", min(g+v, 255)
            , "uchar", max(g-v, 0)
            , "uchar", min(b+v, 255)
            , "uchar", max(b-v, 0)
            ,  "uint", value)

   ; Write pixels to bitmap.
   DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap, "ptr", &BitmapData)

   return pBitmap
}
Mainly - this is much faster C code as you can see here from the assembly https://godbolt.org/z/3Gf341hsb. Also has no dependencies on Gdip_All.ahk (but you still need to run gdip_startup() :D )
Spitzi
Posts: 309
Joined: 24 Feb 2022, 03:45

Re: MCode from 32bit to 64bit

07 Sep 2022, 02:38

Thank you @iseahound and @Xtra.

You guys made my day! I have struggled for 6 months to filter an image that has grayscale stuff on it and colored text, to get just the text and everything else black. Now it is working finally, and it is fast (around 100ms for an image 1500x1500px).

Great Forum and People! Thanks again. Spitzi

Here's the code I ended up with:

Code: Select all

#include Gdip_All_latest.ahk																						
#SingleInstance Force																								
#NoEnv  	


start := A_TickCount
FilterImage("C:\Temp\example5.png") 
duration := A_TickCount - start
MsgBox, Time:%duration%


start := A_TickCount
FilterImageFaster("C:\Temp\example4.png") 
duration := A_TickCount - start
MsgBox, Time:%duration%


return

^<::
Reload 
return


; Filters an image with grayscale stuff and colored text on it to become an image with just the text in white/black
; using standard GDIP functions and iterating through pixels
; every grey pixel (R=G=B ) becomes black
; every color pixel (nor R=G=B) becomes white
FilterImage(imagePath) {
	token := Gdip_Startup()
	
	pBitmap := Gdip_CreateBitmapFromFile(imagePath)
	Gdip_GetImageDimensions(pBitmap, Width, Height)
	
	x := 1
	while (x < Width) {
		y := 1
		while (y < Height) {
		
			ARGB := Gdip_GetPixel(pBitmap, x, y)
			Gdip_FromARGB(ARGB, A, R, G, B)

			if ((R==G) && (R==B)) {
				Gdip_SetPixel(pBitmap, x, y,"0xFF000000")
			} else {
				Gdip_SetPixel(pBitmap, x, y,"0xFFFFFFFF")
			}
			y += 1
			
		}
		x += 1
		; ToolTip, x:%x%
	}
	
	Gdip_Savebitmaptofile(pBitmap, "C:\Temp\filtered.png")
	
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown(token)	
}




; same thing, but using the incredibly fast Functions with Mcode of iseahound and xtra
FilterImageFaster(imagePath) {
	token := Gdip_Startup()
	pBitmap := Gdip_CreateBitmapFromFile(imagePath)

	Gdip_FilterColor(pBitmap, 0xFFfcbf45, 0xFF00FF00, 50)		; alles was ich will in grün
	Gdip_ColorFilter(pBitmap, 0xFF00FF00, 0xFF000000)			; nur grünen Text belassen, Rest schwarz
	Gdip_ColorFilter(pBitmap, 0xFF000000, 0xFFFFFFFF)			; grünen Text weiss


	Gdip_Savebitmaptofile(pBitmap, "C:\Temp\filtered.png")
	
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown(token)	
}








; Filters everything away except pixels of TargetColor
; Courtesy of iseahound
; https://www.autohotkey.com/boards/viewtopic.php?f=76&t=51100&p=478687#p478687
; -----------------------------------------------------------------------
Gdip_FilterColor(pBitmap, key, value, variation) {

   ; Get Bitmap width and height.
   DllCall("gdiplus\GdipGetImageWidth", "ptr", pBitmap, "uint*", width:=0)
   DllCall("gdiplus\GdipGetImageHeight", "ptr", pBitmap, "uint*", height:=0)

   ; Create a pixel buffer.
   VarSetCapacity(Rect, 16, 0)            ; sizeof(Rect) = 16
      NumPut(  width, Rect,  8,   "uint") ; Width
      NumPut( height, Rect, 12,   "uint") ; Height
   VarSetCapacity(BitmapData, 16+2*A_PtrSize, 0)   ; sizeof(BitmapData) = 24, 32
   DllCall("gdiplus\GdipBitmapLockBits"
            ,    "ptr", pBitmap
            ,    "ptr", &Rect
            ,   "uint", 3            ; ImageLockMode.ReadWrite
            ,    "int", 0x26200A     ; Format32bppArgb
            ,    "ptr", &BitmapData)
   Scan0 := NumGet(BitmapData, 16, "ptr")

   ; C source code - https://godbolt.org/z/3Gf341hsb
   static code := 0
   if !code {
      b64 := (A_PtrSize == 4)
         ? "VYnlVlNSikUQi3UIilUcik0gil0kiEX3ikUUiEX2ikUYiEX1O3UMcy2KRgI4RfdyIDpF9nIbikYBOEX1chM40HIPigY4wXIJONhyBYtFKIkGg8YE685YW15dww=="
         : "VlNEilQkOESKXCRAilwkSECKdCRQSInISDnQczGKSAJBOMhyI0Q4yXIeikgBQTjKchZEONlyEYoIOMtyC0A48XIGi0wkWIkISIPABOvKW17D"
      s64 := StrLen(RTrim(b64, "=")) * 3 // 4
      code := DllCall("GlobalAlloc", "uint", 0, "uptr", s64, "ptr")
      DllCall("crypt32\CryptStringToBinary", "str", b64, "uint", 0, "uint", 0x1, "ptr", code, "uint*", s64, "ptr", 0, "ptr", 0)
      DllCall("VirtualProtect", "ptr", code, "ptr", s64, "uint", 0x40, "uint*", op:=0)
   }

   v := abs(variation)
   r := ((key & 0xFF0000) >> 16)
   g := ((key & 0xFF00) >> 8)
   b := ((key & 0xFF))

   ; When doing pointer arithmetic, *Scan0 + 1 is actually adding 4 bytes.
   DllCall(code, "ptr", Scan0, "ptr", Scan0 + 4*width*height
            , "uchar", min(r+v, 255)
            , "uchar", max(r-v, 0)
            , "uchar", min(g+v, 255)
            , "uchar", max(g-v, 0)
            , "uchar", min(b+v, 255)
            , "uchar", max(b-v, 0)
            ,  "uint", value)

   ; Write pixels to bitmap.
   DllCall("gdiplus\GdipBitmapUnlockBits", "ptr", pBitmap, "ptr", &BitmapData)

   return pBitmap
}








; Filters everything away except pixels of TargetColor
; Courtesy of Xtra
; https://www.autohotkey.com/boards/viewtopic.php?style=1&t=98341#p436534
; -----------------------------------------------------------------------
Gdip_ColorFilter(pBitmap, TargetColor, ReplaceColor) 
{
	static ColorFilterMCode
	if (ColorFilterMCode = "")
	{
		if (A_PtrSize = 4)
			mCode := ""
			. "2,x86:VVdWU4PsBItUJCSLTCQoi1wkLItsJByNQgOF0g9JwotU"
			. "JCCByQAAAP/B+AKBywAAAP+F0n44he1+NIt0JBjB4ALB5QKJBC"
			. "Qx/420JgAAAACNFC6J8DsIdAKJGIPABDnQdfODxwEDNCQ5fCQg"
			. "deKDxAQxwFteX13D"
        else
            mCode := ""
			. "2,x64:VlNEi1QkQEGNWQNFhclBD0nZRItMJDhBgcoAAAD/wfsC"
			. "QYHJAAAA/0WFwH5QhdJ+TI1C/0hj20Ux20jB4wJIjTSFBAAAAG"
			. "YuDx+EAAAAAABIjRQOSInIZg8fhAAAAAAARDsIdANEiRBIg8AE"
			. "SDnQde9Bg8MBSAHZRTnYddMxwFtew5CQkJA="
		ColorFilterMCode := MCode(mCode)
	}

	Gdip_GetImageDimensions(pBitmap, w, h)
	Gdip_LockBits(pBitmap, 0, 0, w, h, stride, scan, bitmapData)
	DllCall(ColorFilterMCode, "uint", scan, "int", w, "int", h, "int", Stride, "uint", TargetColor, "uint", ReplaceColor, "cdecl")
	Gdip_UnlockBits(pBitmap, bitmapData)
}


MCode(mcode)
{
    static e := {1:4, 2:1}, c := (A_PtrSize=8) ? "x64" : "x86"
    if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
        return
    if (!DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", 0, "uint*", s, "ptr", 0, "ptr", 0))
        return
    p := DllCall("GlobalAlloc", "uint", 0, "ptr", s, "ptr")
    if (c="x64")
        DllCall("VirtualProtect", "ptr", p, "ptr", s, "uint", 0x40, "uint*", op)
    if (DllCall("crypt32\CryptStringToBinary", "str", m3, "uint", 0, "uint", e[m1], "ptr", p, "uint*", s, "ptr", 0, "ptr", 0))
        return p
    DllCall("GlobalFree", "ptr", p)
}



rlagudgns
Posts: 1
Joined: 10 Jan 2023, 00:46

Re: MCode from 32bit to 64bit

16 Feb 2024, 23:08

Code: Select all

Gdip_ColorFilter(pBitmap, TargetColor, ReplaceColor) 
{
	static ColorFilterMCode
	if (ColorFilterMCode = "")
	{
		if (A_PtrSize = 4)
			mCode := ""
			. "2,x86:VVdWU4PsBItUJCSLTCQoi1wkLItsJByNQgOF0g9JwotU"
			. "JCCByQAAAP/B+AKBywAAAP+F0n44he1+NIt0JBjB4ALB5QKJBC"
			. "Qx/420JgAAAACNFC6J8DsIdAKJGIPABDnQdfODxwEDNCQ5fCQg"
			. "deKDxAQxwFteX13D"
        else
            mCode := ""
			. "2,x64:VlNEi1QkQEGNWQNFhclBD0nZRItMJDhBgcoAAAD/wfsC"
			. "QYHJAAAA/0WFwH5QhdJ+TI1C/0hj20Ux20jB4wJIjTSFBAAAAG"
			. "YuDx+EAAAAAABIjRQOSInIZg8fhAAAAAAARDsIdANEiRBIg8AE"
			. "SDnQde9Bg8MBSAHZRTnYddMxwFtew5CQkJA="
		ColorFilterMCode := MCode(mCode)
	}

	Gdip_GetImageDimensions(pBitmap, w, h)
	Gdip_LockBits(pBitmap, 0, 0, w, h, stride, scan, bitmapData)
	DllCall(ColorFilterMCode, "uint", scan, "int", w, "int", h, "int", Stride, "uint", TargetColor, "uint", ReplaceColor, "cdecl")
	Gdip_UnlockBits(pBitmap, bitmapData)
}
[Mod edit: Added [code][/code] tags. Please use them yourself when posting code!]

Gdip_FilterColor can use Variation.
Gdip_ColorFilter a way to use Variation?

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Google [Bot], OrangeCat, wilkster and 135 guests