GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools
robodesign
Posts: 567
Joined: 30 Sep 2017, 03:59
Facebook: marius.sucan
GitHub: mariussucan
Location: Romania
Contact:

Re: GDI+ standard library 1.45 by tic

28 Oct 2019, 13:02

Hello, guys!

I added 7 new functions to the GDI+ library and fixed some issues related to Gdip_CreateFontFamilyFromFile(). It was not freeing up resources.
Spoiler
I have nothing planned [to add] for the moment ;-) . ... only bug fixes if I find issues.

Download link: https://github.com/marius-sucan/AHK-GDIp-Library-Compilation

Best regards, Marius.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
My home page.
malcev
Posts: 377
Joined: 12 Aug 2014, 12:37

Re: GDI+ standard library 1.45 by tic

08 Nov 2019, 05:15

I suggest to change PrintWindow function - check version of windows and if it is >= 8.1 then add default flag 2.
It will give us opportunity to capture hardware accelerated windows.
https://github.com/tpn/winddk-8.1/blob/master/Include/um/WinUser.h#L4408
robodesign
Posts: 567
Joined: 30 Sep 2017, 03:59
Facebook: marius.sucan
GitHub: mariussucan
Location: Romania
Contact:

Re: GDI+ standard library 1.45 by tic

08 Nov 2019, 06:04

@malcev : thank you .... how to nicely detect windows >= 8.1 ?
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
My home page.
malcev
Posts: 377
Joined: 12 Aug 2014, 12:37

Re: GDI+ standard library 1.45 by tic

08 Nov 2019, 06:12

A_OSVersion?
robodesign
Posts: 567
Joined: 30 Sep 2017, 03:59
Facebook: marius.sucan
GitHub: mariussucan
Location: Romania
Contact:

Re: GDI+ standard library 1.45 by tic

08 Nov 2019, 08:22

Okay, I'll do so in the next version. Soonish.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
My home page.
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: GDI+ standard library 1.45 by tic

08 Nov 2019, 09:20

A_OSVersion is a bit odd in AHK v1, it sometimes returns a string.

To reliably get a number (and not a string): the AHK source code uses RtlGetVersion (or if that's not available, GetVersionEx).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
guest3456
Posts: 2979
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

26 Dec 2019, 17:55

do you guys think we should be looking up the DllCall addresses before hand? especially when doing pixelsearches or imagesearches with GDIP, it could be a noticeable difference

compare these two versions of the Gdip_SetPixel() func.. this benchmark was originally done by Rseding91 in the old forum. the speed increase is non-negligible

Code: Select all

#include Gdip_All.ahk
Setbatchlines -1
pToken := Gdip_Startup()
out := ""
Loop, 2
{
   ;thisfunc := Func("Gdip_SetPixel" . A_Index)
   thisfunc := "Gdip_SetPixel" . A_Index
   tooltip, testing %thisfunc%...
   out .= thisfunc " took " test(thisfunc) " ms`n"
}
tooltip,
msgbox, %out%
Gdip_Shutdown(pToken)
return


Gdip_SetPixel1(pBitmap, x, y, ARGB)
{
   return DllCall("gdiplus\GdipBitmapSetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}

Gdip_SetPixel2(pBitmap, x, y, ARGB)
{
   ;// cant use static initializer becuase we have no module handle at loadtime.. we only have a module handle at runtime after doing LoadLibrary in Gdip_Startup
   static GdipBitmapSetPixelAddr
   if (!GdipBitmapSetPixelAddr)
      GdipBitmapSetPixelAddr := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr"), "AStr", "GdipBitmapSetPixel", "Ptr")
   return DllCall(GdipBitmapSetPixelAddr, A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}


test(func)
{
   Width = 1280
   Height = 720
   pBitmap := Gdip_CreateBitmap(Width, Height)
   G := Gdip_GraphicsFromImage(pBitmap)
   start := A_TickCount
   Loop,%Width%
   {
      X := A_Index - 1
      Loop,%Height%
         %func%(pBitmap, X, A_Index-1, 0xFF0000FF)
   }
   end := A_TickCount - start
   Gdip_DisposeImage(pBitmap)
   Gdip_DeleteGraphics(G)
   return end
}


malcev
Posts: 377
Joined: 12 Aug 2014, 12:37

Re: GDI+ standard library 1.45 by tic

26 Dec 2019, 18:16

Yes, and If You want speed, You do not have to use functions.
robodesign
Posts: 567
Joined: 30 Sep 2017, 03:59
Facebook: marius.sucan
GitHub: mariussucan
Location: Romania
Contact:

Re: GDI+ standard library 1.45 by tic

27 Dec 2019, 17:37

Best is to use.... Bitmap lock bits. A lot more faster.
-------------------------
KeyPress OSD v4: GitHub or forum. (presentation video)
My home page.
guest3456
Posts: 2979
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

29 Dec 2019, 13:31

we're not talking about whether lockbits is faster.. we're talking about the DllCall overhead

AHK_H has two features that are even faster... using its DynaCall() or using its winApi functions that are already built in:

Code: Select all

#include Gdip_All.ahk
Setbatchlines -1
pToken := Gdip_Startup()
out := ""
Loop, 4
{
   ; thisfunc := Func("Gdip_SetPixel" . A_Index)
   thisfunc := "Gdip_SetPixel" . A_Index
   tooltip, testing %thisfunc%...
   out .= thisfunc " took " test(thisfunc) " ms`n"
}
tooltip,
msgbox, %out%
Gdip_Shutdown(pToken)
return


Gdip_SetPixel1(pBitmap, x, y, ARGB)
{
   return DllCall("gdiplus\GdipBitmapSetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}

Gdip_SetPixel2(pBitmap, x, y, ARGB)
{
   ;// cant use static initializer becuase we have no module handle at loadtime.. we only have a module handle at runtime after doing LoadLibrary in Gdip_Startup
   static GdipBitmapSetPixelAddr
   if (!GdipBitmapSetPixelAddr)
      GdipBitmapSetPixelAddr := DllCall("GetProcAddress"
                                             , "Ptr", DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
                                             , "AStr", "GdipBitmapSetPixel"
                                             , "Ptr")
   return DllCall(GdipBitmapSetPixelAddr, A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}

Gdip_SetPixel3(pBitmap, x, y, ARGB)
{
   ;// AHK_H DynaCall()
   ;// https://hotkeyit.github.io/v2/docs/commands/DynaCall.htm
   static GdipBitmapSetPixelDyna := DynaCall("gdiplus\GdipBitmapSetPixel", "tiii")
   %GdipBitmapSetPixelDyna%(pBitmap, x, y, ARGB)
}

Gdip_SetPixel4(pBitmap, x, y, ARGB)
{
   ;// AHK_H built-in WinApi calls
   ;// https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
   GdipBitmapSetPixel(pBitmap, x, y, ARGB)
}


test(func)
{
   Width = 1280
   Height = 720
   pBitmap := Gdip_CreateBitmap(Width, Height)
   G := Gdip_GraphicsFromImage(pBitmap)
   start := A_TickCount
   Loop,%Width%
   {
      X := A_Index - 1
      Loop,%Height%
         %func%(pBitmap, X, A_Index-1, 0xFF0000FF)
   }
   end := A_TickCount - start
   Gdip_DisposeImage(pBitmap)
   Gdip_DeleteGraphics(G)
   return end
}


malcev
Posts: 377
Joined: 12 Aug 2014, 12:37

Re: GDI+ standard library 1.45 by tic

30 Dec 2019, 01:00

As I said before - if You want speed, do not use functions, do not use not needed expressions (A_PtrSize ? "UPtr" : "UInt"), place quotes around types and use ahk64bit
I do not have AHK_H, but on AHK_L 64bit it takes 5 seconds: on my PC.

Code: Select all

#include Gdip_All.ahk
Setbatchlines -1
pToken := Gdip_Startup()
out := ""
Loop, 2
{
   ;thisfunc := Func("Gdip_SetPixel" . A_Index)
   thisfunc := "Gdip_SetPixel" . A_Index
   tooltip, testing %thisfunc%...
   out .= thisfunc " took " test(thisfunc) " ms`n"
}
tooltip,
msgbox, %out%
Gdip_Shutdown(pToken)
return
#include Gdip_All.ahk

Gdip_SetPixel1(pBitmap, x, y, ARGB)
{
   return DllCall("gdiplus\GdipBitmapSetPixel", A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}

Gdip_SetPixel2(pBitmap, x, y, ARGB)
{
   ;// cant use static initializer becuase we have no module handle at loadtime.. we only have a module handle at runtime after doing LoadLibrary in Gdip_Startup
   static GdipBitmapSetPixelAddr
   if (!GdipBitmapSetPixelAddr)
      GdipBitmapSetPixelAddr := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr"), "AStr", "GdipBitmapSetPixel", "Ptr")
   return DllCall(GdipBitmapSetPixelAddr, A_PtrSize ? "UPtr" : "UInt", pBitmap, "int", x, "int", y, "int", ARGB)
}


test(func)
{
   Width = 1280
   Height = 720
   pBitmap := Gdip_CreateBitmap(Width, Height)
   G := Gdip_GraphicsFromImage(pBitmap)
   GdipBitmapSetPixelAddr := DllCall("GetProcAddress", "Ptr", DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr"), "AStr", "GdipBitmapSetPixel", "Ptr")
   start := A_TickCount
   loop 10
   {
      Loop,%Width%
      {
         X := A_Index - 1
         Loop,%Height%
            DllCall(GdipBitmapSetPixelAddr, "ptr", pBitmap, "int", x, "int", A_Index-1, "int", 0xFF0000FF)
      }
   }
   msgbox % A_TickCount - start


   end := A_TickCount - start
   Gdip_DisposeImage(pBitmap)
   Gdip_DeleteGraphics(G)
   return end
}

Return to “Scripts and Functions”

Who is online

Users browsing this forum: Google [Bot] and 78 guests