GDI+ standard library 1.45 by tic

Post your working scripts, libraries and tools for AHK v1.1 and older
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

25 Jan 2017, 19:41

buliasz wrote:In case someone needs it, I've modified Gdip_All.ahk of mmikeww (guest3456) which work with AHK 2.0+ also. I made one bugfix and made additional little changes, so that it can now be used with the "#Warn All" flag enabled.
Surely there are more changes needed for "#Warn All", but they appear only when you use a particular function. The ones I used are working now.
You can get it here.
please submit a pull request and i will accept it and merge the changes

guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: GDI+ standard library 1.45 by tic

10 Feb 2017, 18:50

I have merged the changes from @buliasz and we've bumped the version to v1.51:

backward compatible with AHK v1.1 and forward-compatible with AHK v2:

https://github.com/mmikeww/AHKv2-Gdip

serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

03 Mar 2017, 06:36

Hi, has anyone encountered this problem with GDIP:
- top 25 pixels of GDIP-created Gui are "un-clickable" when Gui is inactive?

I.e. if I create GDIP Gui, then activate some other window, then click on top 25pix of this Gui - it doesn't get activated. If I click below top 25 pix - it does get activated, then clicking on top 25pix of Gui responds normally.
Any ideas?
I have the latest version of AHK, GDIP lib 1.45 by TIC and Win7 32
serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 02:21

Hi folks!
What is the fastest way to test if image created with GDIP actually contains image?
When I create bitmap and copy image there from image file - it works 99% of the time, but occasionally GDIP function returns empty image (I mean it returns handle that doesn't contain any image). Since I use this GDIP func thousands of times in a relatively short period of time, I would like to know what is the fastest way to test GDIP image.
Any input is welcome and appreciated!
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 02:44

serg wrote: When I create bitmap and copy image there from image file - it works 99% of the time, but occasionally GDIP function returns empty image (I mean it returns handle that doesn't contain any image).
Check if the functions you are using sets ErrorLevel or the underlying windows functions sets A_LastError. If there is no image, maybe it doesn't have a width and height.

Good luck
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 04:31

Hi, has anyone encountered this problem with GDIP
It has something to do with Gui,new . I have the problem on winXP but not on win10.

You can try this code ,the green gui can be moved on winxp the black not at the top part.I solve with deleting the Gui,new codeline or giving it a name or number.
Maybe I use the "Gui, new" in a wrong way but as it works without it I never looked into it..........

Code: Select all

; Many thanks to Tic for gdip library
; http://www.autohotkey.com/forum/topic32238.html 
; original layered window

SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
onexit bye


If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}




gui,  new
Gui,  -Caption +E0x80000 +LastFound +OwnDialogs +Owner +hwndhwnd +alwaysontop
Gui,  Show, NA

; this works
gui,  new
Gui, name: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +hwndhwnd_name +alwaysontop
Gui, name: Show, NA 


w:=150
h:=150

hbm := CreateDIBSection(w,h)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
pGraphics := Gdip_GraphicsFromHDC(hdc)

Gdip_SetSmoothingMode(pGraphics,4)
Gdip_SetInterpolationMode(pGraphics,7)
Gdip_GraphicsClear(pGraphics,0xff202020)


UpdateLayeredWindow(hwnd, hdc,(a_screenwidth-w)//2,(a_screenheight-h)//2,w,h)

Gdip_GraphicsClear(pGraphics,0xff03BC1B)

UpdateLayeredWindow(hwnd_name, hdc,(a_screenwidth-w)//2-300,(a_screenheight-h)//2,w,h)

OnMessage(0x2A3,"OnMouseLeave")
; OnMessage(0x232, "WM_EXITSIZEMOVE")
OnMessage(0x200,"OnMouseMove")
; OnMessage(0x216,"WM_Move")  ;lock only horizontal movement
; OnMessage(0x204, "WM_RBUTTONDOWN")

OnMessage(0x201,"WM_LBUTTONDOWN")


VarSetCapacity(tme,16,0)
NumPut(16,tme,0), NumPut(2,tme,4), NumPut(hwnd,tme,8)




return

!v::listvars


WM_LBUTTONDOWN(wParam,lParam,msg,hwnd){
 
    x := lParam & 0xFFFF
    y := lParam >> 16
    
    ;tooltip x=%x% y=%y% mousebutton
PostMessage, 0xA1, 2 
}

WM_RBUTTONDOWN(wParam,lParam,msg,hwnd){

    x := lParam & 0xFFFF
    y := lParam >> 16
}


OnMouseLeave(){
    tooltip leaving window
}


WM_EXITSIZEMOVE(wParam,lParam,msg,hwnd){  ;to autosave last position when moving gui


}




OnMouseMove( wParam, lParam, Msg,hwnd ) {
global
DllCall( "TrackMouseEvent","uint",&tme )
    x := lParam & 0xFFFF
    y := lParam >> 16
    
    tooltip Over window
}

WM_Move(wP,lP,msg)
  {

    gui +lastfound
    wingetpos,x,y,w,h

    If (msg = 0x3) {
        x := lP << 48 >> 48  
        y := lP << 32 >> 48  
      }
    Else If (msg = 0x216)
        NumPut(y,lP+0,4,"Int"), NumPut(y+h,lP+0,12,"Int")

  }





esc::
bye:

SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(pGraphics)
Gdip_Shutdown(pToken)
ExitApp




















serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 10:22

Helgef wrote: Check if the functions you are using sets ErrorLevel or the underlying windows functions sets A_LastError. If there is no image, maybe it doesn't have a width and height.
Good luck
Helgef, thanks for response!
I have 2 suspect GDIP functions:

Code: Select all

Gdip_GraphicsFromImage(pBitmap){
	DllCall("gdiplus\GdipGetImageGraphicsContext", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
	return pGraphics
}
Gdip_CreateBitmap(Width, Height, Format=0x26200A){
    DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", Width, "int", Height, "int", 0, "int", Format, A_PtrSize ? "UPtr" : "UInt", 0, A_PtrSize ? "UPtr*" : "uint*", pBitmap)
    Return pBitmap
}
Do you know if there is a way to make them set ErrorLevel if they fail (return handle to empty image)?

As for Height/Weight - you mean getting them thru Gdip_GetImageWidth/Height() could be the fastest way to test image?

Thanks!
serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 10:32

Noname, thanks for your input !
I'll try your code. Btw, I have this problem only on my other Win 7 machine, but not on Win 8.1
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 10:56

Hi serg.
serg wrote:Do you know if there is a way to make them set ErrorLevel if they fail (return handle to empty image)?
According to msdn the functions should return 0 on success. That is add r:=DllCall("gdi...) and check that r==0.
serg wrote:As for Height/Weight - you mean getting them thru Gdip_GetImageWidth/Height() could be the fastest way to test image?
I meant something like that, but checking the return value would probably be much faster.

Good luck.
serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 11:41

Helgef, I really appreciate your help! Thanks!
serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 11:49

noname wrote: It has something to do with Gui,new . I have the problem on winXP but not on win10.
Noname, you are absolutely correct, - not using "Gui,new" fixes the problem.
Thank you for setting me on the right path! :-)

BTW, should it be reported to Lexikos as a bug?
just me
Posts: 9406
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GDI+ standard library 1.45 by tic

17 Apr 2017, 15:38

Hi noname,

did you try

Code: Select all

gui,  new, -Caption +E0x80000 +LastFound +OwnDialogs +Owner +hwndhwnd +alwaysontop
?

Also, which AHK version are you using?
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: GDI+ standard library 1.45 by tic

18 Apr 2017, 02:49

Code: Select all

gui,  new, -Caption +E0x80000 +LastFound +OwnDialogs +Owner +hwndhwnd +alwaysontop
Thanks , just me.
Your suggestion works on winXP , I am using ahk version 1.1.25.01.
I guess creating an unnamed, unnumbered Gui can have its uses.
Since I use this GDIP func thousands of times in a relatively short period of time
Hi serg,
Maybe it is unrelated but I remember when using a resize function start/stopping gdip inside the function caused problems when using it repeatedly like resizing all images in a directory.It worked well if gdip was started only once at the beginning of the program outside the function.
serg
Posts: 56
Joined: 21 Mar 2015, 05:33

Re: GDI+ standard library 1.45 by tic

18 Apr 2017, 03:09

Hi Noname,
GDIP itself is started only once in my script, I don't know yet what exactly causes the problems, but I think Helgef's suggestion:

Code: Select all

if Error := DLLCall(...) ...
will catch the perpetrator soon
Thanks again!
iseahound
Posts: 1427
Joined: 13 Aug 2016, 21:04
Contact:

Re: GDI+ standard library 1.45 by tic

21 Apr 2017, 23:19

Does anyone have a working GdipSaveImageToStream?

I tried messing with some code I found here, but it's beyond me.
https://autohotkey.com/board/topic/8552 ... etobuffer/


Specifically this code. (which can be inserted at the end of Gdip_SaveBitmapToFile)

Code: Select all

   Buffer := 0
   ; Save Image to Stream and copy it to Buffer
   DllCall( "ole32\CreateStreamOnHGlobal", UInt,0, Int,1, UIntP,pStream )
   DllCall( "gdiplus\GdipSaveImageToStream", Ptr,pBitmap, UInt,pStream, UInt,pCodec, UInt,pEncP )
   ;DllCall( "gdiplus\GdipDisposeImage", Ptr,pBitmap )
   DllCall( "ole32\GetHGlobalFromStream", UInt,pStream, UIntP,hData )
   pData := DllCall( "GlobalLock", UInt,hData )
   nSize := DllCall( "GlobalSize", UInt,pData )
   VarSetCapacity( Buffer, nSize, 0 )
   DllCall( "RtlMoveMemory", UInt,&Buffer, UInt,pData, UInt,nSize )
   DllCall( "GlobalUnlock", UInt,hData )
   DllCall( NumGet( NumGet( 1*pStream ) + 8 ), UInt,pStream )
   DllCall( "GlobalFree", UInt,hData )
   
   return Buffer
I'm trying to avoid File I/O since the data will be converted to base64 and sent via HTTP.
User avatar
noname
Posts: 515
Joined: 19 Nov 2013, 09:15

Re: GDI+ standard library 1.45 by tic

22 Apr 2017, 08:59

Does anyone have a working GdipSaveImageToStream?
Here is some more "messing around" !

Code: Select all


SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1



If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}


---------------- create red square bitmap for test ----------

pBitmap:=Gdip_CreateBitmap(10,10)
pGraphics:=Gdip_GraphicsFromImage(pBitmap)
Gdip_GraphicsClear(pGraphics, 0xffff0000)


---------------- ---------------- ---------------- ----------


encoded:=Gdip_EncodeBitmapTo64string(pBitmap, "png")
msgbox %encoded%




---------------- test create the image ---------------- 

pBm:=get_bitmapfrom64(encoded)
Gdip_SaveBitmapToFile(pbm,"red_square.png")

Gdip_Shutdown(pToken)
exitapp


; based on gdip_all.ahk save bitmap to file

Gdip_EncodeBitmapTo64string(pBitmap, ext, Quality=75)
{
	
	if Ext not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
		return -1
	Extension := "." Ext

	DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", nCount, "uint*", nSize)
	VarSetCapacity(ci, nSize)
	DllCall("gdiplus\GdipGetImageEncoders", "uint", nCount, "uint", nSize, Ptr, &ci)
	if !(nCount && nSize)
		return -2
	


		Loop, %nCount%
		{
			sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
			if !InStr(sString, "*" Extension)
				continue
			
			pCodec := &ci+idx
			break
		}
	
	
	if !pCodec
		return -3

	if (Quality != 75)
	{
		Quality := (Quality < 0) ? 0 : (Quality > 100) ? 100 : Quality
		if Extension in .JPG,.JPEG,.JPE,.JFIF
		{
			DllCall("gdiplus\GdipGetEncoderParameterListSize", Ptr, pBitmap, Ptr, pCodec, "uint*", nSize)
			VarSetCapacity(EncoderParameters, nSize, 0)
			DllCall("gdiplus\GdipGetEncoderParameterList", Ptr, pBitmap, Ptr, pCodec, "uint", nSize, Ptr, &EncoderParameters)
			Loop, % NumGet(EncoderParameters, "UInt")      
			{
				elem := (24+(A_PtrSize ? A_PtrSize : 4))*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
				if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
				{
					p := elem+&EncoderParameters-pad-4
					NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
					break
				}
			}      
		}
	}
	

DllCall("Ole32.dll\CreateStreamOnHGlobal", Ptr, 0, Int, True, PtrP, pStream)

E:=DllCall( "gdiplus\GdipSaveImageToStream", Ptr,pBitmap, Ptr,pStream, Ptr, pCodec, uint, p ? p : 0)
 
DllCall( "ole32\GetHGlobalFromStream", Ptr ,pStream , UIntP,hData )
pData :=DllCall("Kernel32.dll\GlobalLock", Ptr, hData, UPtr)
nSize := DllCall( "GlobalSize", UInt,pData )

VarSetCapacity( Bin, nSize, 0 )
 DllCall( "RtlMoveMemory", Ptr, &Bin , Ptr, pData , UInt, nSize )
 DllCall( "GlobalUnlock", Ptr,hData )
 DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), Ptr, pStream)
 DllCall( "GlobalFree", Ptr,hData )
 
 
   DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &Bin, "UInt", nSize, "UInt", 0x01, "Ptr", 0, "UIntP", enc64Len)
   VarSetCapacity(enc64, enc64Len*2, 0)
   DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &Bin, "UInt", nSize, "UInt", 0x01, "Ptr", &enc64, "UIntP", enc64Len)
   Bin := ""
   VarSetCapacity(Bin, 0)
   VarSetCapacity(enc64, -1)

Return enc64
}


; based upon just me code: https://autohotkey.com/board/topic/93292-image2include-include-images-in-your-scripts/

get_bitmapfrom64(enc64){
If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &enc64, "UInt", 0, "UInt", 0x01, "Ptr", 0, "UIntP", BinLen, "Ptr", 0, "Ptr", 0)
   Return False
VarSetCapacity(Bin, BinLen, 0)
If !DllCall("Crypt32.dll\CryptStringToBinary", "Ptr", &enc64, "UInt", 0, "UInt", 0x01, "Ptr", &Bin, "UIntP", BinLen, "Ptr", 0, "Ptr", 0)
   Return False

hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", BinLen, "UPtr")
pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &Bin, "UPtr", BinLen)
DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)

DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
Return pBitmap
}







User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

27 Apr 2017, 05:45

The examples for Matrices are off.
To be more precise the MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1 is wrong.
Just making the colours values negative will result in negative results and clamping will lead to them being set to 0.
So instead of inverting the colours this matrix will make everything black.
The correct Matrix should be MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|1|1|1|0|1.
I will test this and confirm this then make a pull request on github.
Recommends AHK Studio
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: GDI+ standard library 1.45 by tic

27 Apr 2017, 13:55

BTW I found this awesome description for Gradients:
https://www.codeproject.com/Articles/20 ... -made-easy
( We're still missing path gradients )
And this API description:
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Recommends AHK Studio

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: JoeWinograd and 80 guests