Page 9 of 23

Re: GDI+ standard library 1.45 by tic

Posted: 25 Jan 2017, 19:41
by guest3456
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

Re: GDI+ standard library 1.45 by tic

Posted: 10 Feb 2017, 18:50
by guest3456
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

Re: GDI+ standard library 1.45 by tic

Posted: 03 Mar 2017, 06:36
by serg
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

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 02:21
by serg
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!

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 02:44
by Helgef
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

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 04:31
by noname
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





















Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 10:22
by serg
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!

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 10:32
by serg
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

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 10:56
by Helgef
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.

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 11:41
by serg
Helgef, I really appreciate your help! Thanks!

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 11:49
by serg
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?

Re: GDI+ standard library 1.45 by tic

Posted: 17 Apr 2017, 15:38
by just me
Hi noname,

did you try

Code: Select all

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

Also, which AHK version are you using?

Re: GDI+ standard library 1.45 by tic

Posted: 18 Apr 2017, 02:49
by noname

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.

Re: GDI+ standard library 1.45 by tic

Posted: 18 Apr 2017, 03:09
by serg
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!

Re: GDI+ standard library 1.45 by tic

Posted: 21 Apr 2017, 23:19
by iseahound
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.

Re: GDI+ standard library 1.45 by tic

Posted: 22 Apr 2017, 08:59
by noname
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
}








Re: GDI+ standard library 1.45 by tic

Posted: 27 Apr 2017, 05:45
by nnnik
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.

Re: GDI+ standard library 1.45 by tic

Posted: 27 Apr 2017, 06:20
by nnnik

Re: GDI+ standard library 1.45 by tic

Posted: 27 Apr 2017, 07:52
by guest3456

Re: GDI+ standard library 1.45 by tic

Posted: 27 Apr 2017, 13:55
by nnnik
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