Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GDI+ standard library 1.45 by tic


  • Please log in to reply
1385 replies to this topic
tic
  • Members
  • 1934 posts
  • Last active: Dec 21 2015 01:05 PM
  • Joined: 22 Apr 2007
pBitmap := CreateDIBsection(width, height)

isn't a pointer to a gdi+ bitmap. That is a device independent bitmap
You need

pBitmap := Gdip_CreateBitmap(width, height)


nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Thanks!

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
Hi tic, I've created a tiny class which allows more natural manipulation of Graphics Objects. For example, on the MSDN it is common to see code like this:
graphics.SetSmoothingMode(SmoothingModeHighSpeed);
Well with my class it is the same:
graphics.SetSmoothingMode(SmoothingModeHighSpeed := 1)
I hope to be able to do more with this to make translating C++/C# GDI+ code to AutoHotkey code more natural. Of course, it relies on your library :p and I have it appended to the bottom of my copy.
; Graphics object
; Allows a more natural manipulation of pointers to graphics
; For example, the following C++:
;; graphics.SetSmoothingMode(4);
; is exactly the same in AutoHotkey (minus the ending ';' ), provided the
; graphics was obtained with ``new Gdip_graphics()``
class Gdip_graphics
{
	; Create a new graphics object
	; specify either new Gdip_graphics("HDC", hdc)
	;          or    new Gdip_graphics("Image", pBitmap)
	__New(FromType, From){
		this.ptr := Gdip_GraphicsFrom%FromType%(From)
	}

	; Graphics methods
	; Dynamically works for C#-like calls such as G.FillRectangle()
	__Call(name, p*){
		Gdip_%name%(this.ptr, p*)
	}

	; Shutdown
	; specify G := ""
	__Delete(){
		Gdip_DeleteGraphics(this.ptr)
	}
}
As you can see, it's quite simple, only a few lines of AHK_L code to implement.

Here's a real example:
pToken := Gdip_Startup()
pBitmap := Gdip_CreateBitmap(200, 200)
[color=red]G := new Gdip_graphics("Image", pBitmap)
G.SetSmoothingMode(4)[/color] ; antialias
pBrush := Gdip_BrushCreateSolid()
[color=red]G.FillRectangle(pBrush, 20, 20, 20, 20)[/color]
Gdip_SaveBitmapToFile(pBitmap, A_ScriptDir "\test.png")
Run %A_ScriptDir%\test.png

; cleanup
Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmap)
[color=red]G := ""[/color]
Gdip_Shutdown(pToken)
In any case, it saves me time and effort :)

tic
  • Members
  • 1934 posts
  • Last active: Dec 21 2015 01:05 PM
  • Joined: 22 Apr 2007
Hi nimda, I do like the idea of having objects.
I had thought of doing something like this for a while, but worried about bugs in AHK L, although I'm sure they have been fixed now.

It would be great if there was an inbuilt variable in AHK for a function to know whether it was called from another function, and if so then the name of that function, which would allow automatic cleanup.

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
One problem I see is passing objects. For a brush, you'd have to either use pBrush[] or pBrush.ptr when passing it to a function, OR modify each function to use
If IsObject(pBrush)
   pBrush := pBrush.ptr ; or pBrush[]
...which would slow down and bloat the library.

This will be fixed in a far-off version of AHK. There's a wishlist topic on __Str().

elvnus
  • Members
  • 17 posts
  • Last active: Nov 16 2014 01:03 AM
  • Joined: 14 Mar 2011
Is there any troubleshooting info about this script somewhere? Because I couldn't manage to run this, even the examples :S

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010

Is there any troubleshooting info about this script somewhere? Because I couldn't manage to run this, even the examples :S

You need to be more specific, for a start.

elvnus
  • Members
  • 17 posts
  • Last active: Nov 16 2014 01:03 AM
  • Joined: 14 Mar 2011

You need to be more specific, for a start.


Yeah I thought so, actually I don't know what info could be helpful to identify my problem :?.

The script will run but doesn't show anything on screen.

I'm using Windows 7 x64, onboard ATI HD 3200, Autohotkey v1.0.92.02

Leef_me
  • Moderators
  • 8510 posts
  • Last active: Sep 10 2015 05:50 AM
  • Joined: 08 Apr 2009
"... I couldn't manage to run this, even the examples ..."

"The script will run but doesn't show anything on screen."

Phrases like "The script" and "this" are not specific.

You have clarified what version if AHk you are running, but have not identifies what script(s) you are trying to make work. :cry:

:?: GDIP requires Gdip.ahk, have you downloaded it?

Most, if not all of the example scripts have these lines in the script
; Uncomment if Gdip.ahk is not in your standard library
;#Include, Gdip.ahk

:?: Have you made the needed changes to your system ?

elvnus
  • Members
  • 17 posts
  • Last active: Nov 16 2014 01:03 AM
  • Joined: 14 Mar 2011
My bad, sorry I didn't express myself well, forgot to mention that I tried to run examples #1, #4 and this as well, I had included the main GDI+ script on these...

The example scripts seemed to work fine, had no errors or whatsoever, but I just didn't see any drawings on screen.

If there's anything you need to know to solve this, please let me know.

Deo
  • Members
  • 199 posts
  • Last active: Jan 31 2014 03:19 PM
  • Joined: 16 May 2010

Ok, I've bitten the bullet and made this library compatible with 64-bit AutoHotkey myself. It can be found here.

just want to say thanks, fincs, i'm sure it took much time to convert all this...
it was a bit hard to find his post and i think link at least must be added to the first post
<!-- m -->http://www.autohotke... ... 442#470442<!-- m -->

elvnus
  • Members
  • 17 posts
  • Last active: Nov 16 2014 01:03 AM
  • Joined: 14 Mar 2011

Ok, I've bitten the bullet and made this library compatible with 64-bit AutoHotkey myself. It can be found here.

just want to say thanks, fincs, i'm sure it took much time to convert all this...
it was a bit hard to find his post and i think link at least must be added to the first post
<!-- m -->http://www.autohotke... ... 442#470442<!-- m -->


Man thanks a lot! It's working!!! :D :D :D :D
Indeed, must be added there!

kenn
  • Members
  • 407 posts
  • Last active: Jan 14 2015 08:16 PM
  • Joined: 11 Oct 2010
Hi, I have a head-tracking project here <!-- m -->http://www.autohotke...pic.php?t=72360<!-- m --> it's moving mouse by head movement with WebCam. I think it's quite possible with GDIP Library but it's far beyond my poor programming skill. I posted a working blink click C code (it isn't tracking head). I compiled it using OpenCV Library. Maybe it is compiled into a dll and called from AHK.
I need your views about it.

gamax92
  • Members
  • 411 posts
  • Last active: Aug 06 2013 05:00 AM
  • Joined: 05 Dec 2010
I used GDIP to make a rotating 3D cube

; gdi+ ahk tutorial 2 written by tic (Tariq Porter)
; Requires Gdip.ahk either in your Lib folder as standard library or using #Include
;
; Tutorial to draw a single ellipse and rectangle to the screen, but just the outlines of these shapes

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

; Uncomment if Gdip.ahk is not in your standard library
#Include, Gdip.ahk

; Initilize Random Junk

lOx := []
lOy := []
lOz := []
lRx := []
lRy := []
lRz := []
scrX := []
scrY := []
s := []
c := []

lOx[1,1] := -50
lOx[1,2] := 50
lOy[1,1] := 50
lOy[1,2] := 50
lOz[1,1] := 50
lOz[1,2] := 50

lOx[2,1] := 50
lOx[2,2] := 50
lOy[2,1] := -50
lOy[2,2] := 50
lOz[2,1] := 50
lOz[2,2] := 50

lOx[3,1] := 50
lOx[3,2] := 50
lOy[3,1] := 50
lOy[3,2] := 50
lOz[3,1] := -50
lOz[3,2] := 50

lOx[4,1] := -50
lOx[4,2] := -50
lOy[4,1] := -50
lOy[4,2] := 50
lOz[4,1] := 50
lOz[4,2] := 50

lOx[5,1] := -50
lOx[5,2] := -50
lOy[5,1] := 50
lOy[5,2] := 50
lOz[5,1] := -50
lOz[5,2] := 50

lOx[6,1] := -50
lOx[6,2] := 50
lOy[6,1] := -50
lOy[6,2] := -50
lOz[6,1] := 50
lOz[6,2] := 50

lOx[7,1] := -50
lOx[7,2] := 50
lOy[7,1] := 50
lOy[7,2] := 50
lOz[7,1] := -50
lOz[7,2] := -50

lOx[8,1] := -50
lOx[8,2] := 50
lOy[8,1] := -50
lOy[8,2] := -50
lOz[8,1] := -50
lOz[8,2] := -50

lOx[9,1] := -50
lOx[9,2] := -50
lOy[9,1] := -50
lOy[9,2] := 50
lOz[9,1] := -50
lOz[9,2] := -50

lOx[10,1] := 50
lOx[10,2] := 50
lOy[10,1] := -50
lOy[10,2] := -50
lOz[10,1] := -50
lOz[10,2] := 50

lOx[11,1] := 50
lOx[11,2] := 50
lOy[11,1] := -50
lOy[11,2] := 50
lOz[11,1] := -50
lOz[11,2] := -50

lOx[12,1] := -50
lOx[12,2] := -50
lOy[12,1] := -50
lOy[12,2] := -50
lOz[12,1] := -50
lOz[12,2] := 50

Loop, 6
{
lOx[12 + a_index,1] := 0
lOx[12 + a_index,2] := 0
lOy[12 + a_index,1] := 0
lOy[12 + a_index,2] := 0
lOz[12 + a_index,1] := 0
lOz[12 + a_index,2] := 0
NumLines := 12 + a_index
}

PI := 3.141592
Width := A_ScreenWidth, Height := A_ScreenHeight

Loop, 360
{
s[a_index] := Sin(a_index * (PI / 180))
c[a_index] := COS(a_index * (PI / 180))
}

xCenter := Width / 2
yCenter := Height / 2
zCenter := 256
Scale := 1024
theta := 0
phi := 0
thetaRot := 2
phiRot := 2
Clock := 0

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

Gui, 1: -Caption +E0x80000 +LastFound +OwnDialogs +Owner +AlwaysOnTop
Gui, 1: Show, NA
hwnd1 := WinExist()

Loop
{
TickCount := A_TickCount
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pPen1 := Gdip_CreatePen(0xFFFFFFFF, 12)
pPen2 := Gdip_CreatePen(0xFF0000FF, 6)

Loop, % NumLines - 12
{
lOz[12 + a_index,2] := Sin(Clock+a_index) * 50
lOy[12 + a_index,2] := Cos(Clock+a_index) * 50
}

Loop, % NumLines
{
   lRx[a_index,1] := (lOx[a_index,1] * -1) * s[theta+1] + lOy[a_index,1] * c[theta+1]
   lRy[a_index,1] := (lOx[a_index,1] * -1) * c[theta+1] * s[phi+1] - lOy[a_index,1] * s[theta+1] * s[phi+1] - lOz[a_index,1] * c[phi+1] + 1
   lRz[a_index,1] := (lOx[a_index,1] * -1) * c[theta+1] * c[phi+1] - lOy[a_index,1] * s[theta+1] * c[phi+1] + lOz[a_index,1] * s[phi+1]

   lRx[a_index,2] := (lOx[a_index,2] * -1) * s[theta+1] + lOy[a_index,2] * c[theta+1]
   lRy[a_index,2] := (lOx[a_index,2] * -1) * c[theta+1] * s[phi+1] - lOy[a_index,2] * s[theta+1] * s[phi+1] - lOz[a_index,2] * c[phi+1] + 1
   lRz[a_index,2] := (lOx[a_index,2] * -1) * c[theta+1] * c[phi+1] - lOy[a_index,2] * s[theta+1] * c[phi+1] + lOz[a_index,2] * s[phi+1]

   IF ((lRz[a_index,1] + zCenter) != 0)
   {
      scrX[a_index,1] := Scale * (lRx[a_index,1] / (lRz[a_index,1] + zCenter)) + xCenter
      scrY[a_index,1] := Scale * (lRy[a_index,1] / (lRz[a_index,1] + zCenter)) + yCenter
   }

   IF ((lRz[a_index,2] + zCenter) != 0)
   {
      scrX[a_index,2] := Scale * (lRx[a_index,2] / (lRz[a_index,2] + zCenter)) + xCenter
      scrY[a_index,2] := Scale * (lRy[a_index,2] / (lRz[a_index,2] + zCenter)) + yCenter
   }
}
Loop, 2
{
   b_index := a_index
   Loop, % NumLines
   {
      Gdip_DrawLine(G, pPen%b_index%, scrX[a_index,1], scrY[a_index,1], scrX[a_index,2], scrY[a_index,2])
   }
}
 
theta := Mod(theta + thetaRot,360)
phi := Mod(phi + phiRot,360)
Clock += .1

UpdateLayeredWindow(hwnd1, hdc, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2), Width, Height)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
Sleep, % 33 - (A_TickCount - TickCount)
}
Return

;#######################################################################
Esc::ExitApp

Exit:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp
Return

Isint it awesome?

Better framelimiter made, now runs at 30 fps

EDIT: Added hotkey for Esc to end program.

kenn
  • Members
  • 407 posts
  • Last active: Jan 14 2015 08:16 PM
  • Joined: 11 Oct 2010
wow, very nice work gamax92. We can make 3D screen-saver with this, thanks.