Looking for efficiency tips related to working with graphics.

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Hellbent
Posts: 2109
Joined: 23 Sep 2017, 13:34

Looking for efficiency tips related to working with graphics.

23 Jun 2018, 05:06

Below I have a simple script that creates a effect similar to the matrix scrolling numbers/symbols. As it is right now there are no problems, it runs fine, however if I wanted to scale it up it will quickly become sluggish. So if anyone has some pointers on ways that this could be improved/edited/done with another approach I would be thankful.

It should be noted that although I am using this script as the basis of my query, the real goal is for animating graphics in general.
So if you have any tips or tricks that you use or are aware of I would love to hear them.

This script is run ready, and all required gdip functions are included at the bottom of the script.

Preview
Spoiler

Code: Select all

#SingleInstance,Force
SetBatchLines,-1
OnExit,GuiClose
global BC:=["Black","White","Yellow","Lime","Maroon","Aqua","Purple","0077ff","000211"],BackgroundBrush,IsOn,pButton:={},Win:={W:350,H:250},String:={},letter_Array:=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0","!","@","#","$","%","^","&","*","(",")","-","_","=","+","~","<",",",".","?",":",";",">","|","\"," "],colours:=["ff00ff00","ff036F19","ff086714","ff24D95B","ff0D8422","ff00bb00","ff00aa00","ff11ff11","ff22ff22","ff33aa33","ff33dd33"]
SetUp()
return
GuiClose:
GuiEscape:
*^ESC::
	pButton[A_GuiControl].Button_Press()
	Gdip_DeleteBrush(BackgroundBrush)
	Loop,% String.Length()
		DeleteObject(String[A_Index].Bitmap)
	Layered_Window_ShutDown(Win)
	ExitApp
Game_Loop:
	Critical
	Fill_Box(Win.G,BackgroundBrush,0,0,Win.W,Win.H)
	Loop,% String.Length()
		String[A_Index].Update()
	UpdateLayeredWindow(Win.hwnd, Win.hdc)
	return
Class Strings	{
	__New(x,y,w,h){
		This.X:=x,This.Y:=y,This.W:=w,This.H:=h
		This.Font_Size:=RandomNumber(6,18),col:=RandomNumber(1,10),This.Counter:=RandomNumber(0,80),This.Colour:=colours[col]
		This.Speed:=floor(This.Font_Size/4)
		This.Create_Bitmap()
	}
	Create_Bitmap(){
		DeleteObject(This.Bitmap)
		This.Bitmap:=Gdip_CreateBitmap(This.W,This.H)
		temp_Array:="",This.Array1:=[]
		loop 70	{
			val:=RandomNumber(1,34)
			(val>30)?(temp_Array.=" `n",This.Array1[A_Index]:=" "):(temp_Array.=Letter_Array[val] "`n",This.Array1[A_Index]:=Letter_Array[val])
		}
		g:=Gdip_GraphicsFromImage(This.Bitmap),Gdip_SetSmoothingMode(g,4)
		Gdip_TextToGraphics(g,temp_array,"s" This.Font_Size " r5 c" This.Colour " Bold Center","Chiller",20,400)	
		Gdip_DeleteGraphics(g)	
	}
	Change_Things(){
		DeleteObject(This.Bitmap)
		This.Bitmap:=Gdip_CreateBitmap(This.W,This.H)
		temp_Array:=""
		loop 70	{
			rn:=RandomNumber(1,5)			
			(rn=3)?(val:=RandomNumber(1,61),temp_Array.=Letter_Array[val] "`n"):(temp_Array.=This.Array1[A_Index] "`n")
		}
		g:=Gdip_GraphicsFromImage(This.Bitmap),Gdip_SetSmoothingMode(g,4)
		Gdip_TextToGraphics(g,temp_array,"s" This.Font_Size " r5 c" This.Colour " Bold Center","Chiller",20,400)	
		Gdip_DeleteGraphics(g)	
	}
	UpDate(){
		This.y+=This.Speed
		if(++This.Counter>85)
			rn2:=RandomNumber(0,80),This.Counter:=rn2,This.Change_Things()
		if(This.Y>Win.H){
			This.Y:=RandomNumber(-400,-1150),This.X:=5*RandomNumber(0,Win.W//5)
			This.Font_Size:=RandomNumber(6,22),This.Speed:=floor(This.Font_Size/4)
			This.Create_Bitmap()
		}
		if(This.Y>-400&&This.Y<Win.H)
			Gdip_DrawImage(Win.G, This.BitMap,This.X,This.Y,This.W,This.H)
	}
}
SetUp(){
	Gui,1:+AlwaysOnTop -caption -DPIScale
	Gui,1:Color,% BC[9]
	Gui,1:Font,% "c" BC[8] " s10 Bold Q5",Microsoft YaHei UI
	Gui,1:Add,Text,x50 y5 w250 h20 BackgroundTrans Center gMW , HB
	Add_Border_Trim(1,0,0,350,250,BC[8],2),Add_Border_Trim(1,5,30,340,215,BC[8]),Add_Border_Trim(1,50,5,250,20,BC[8])
	pButton.Push(New Progress_Button("1",pButton.Length()+1,"BP",20,175,150,30,"BLACK",BC[8],"222222","444444","181818","Start",5))
	pButton.Push(New Progress_Button("1",pButton.Length()+1,"BP",180,175,150,30,"BLACK",BC[8],"222222","444444","181818","Stop",5))
	pButton.Push(New Progress_Button("1",pButton.Length()+1,"GuiClose",10,210,330,30,"BLACK",BC[8],"222222","444444","181818","Exit",5))
	Gui,1:Show,% "w" Win.W " h" Win.H,HB MATRIX
	Win:=Layered_Window_SetUp(4,5,30,340,215,2,"+Parent1 -Caption -DPIScale")
	BackgroundBrush:=New_Brush("001100","ff")
	Fill_Box(Win.G,BackgroundBrush,0,0,Win.W,Win.H)
	Gdip_DeleteBrush(BackgroundBrush)
	UpdateLayeredWindow(Win.hwnd, Win.hdc, Win.X, Win.Y, Win.W, Win.H)
	BackgroundBrush:=New_Brush("001100","55"),x:=0
	Loop, % Win.W//5 ;+ 0
		y:=RandomNumber(-400,-1150),String[A_Index]:=New Strings(x,y,20,400),x+=5	
}
BP(){
	pButton[A_GuiControl].Button_Press()
	if(A_GuiControl=1){
		SetTimer,Game_Loop,30
		IsOn:=1
	}else	{
		SetTimer,Game_Loop,Off
		IsOn:=0
	}
}
MW(){
	SetTimer,Game_Loop,Off
	PostMessage,0xA1,2
	While(GetKeyState("LButton"))
		Sleep,10
	if(IsOn=1)
		SetTimer,Game_Loop,30
}	
RandomNumber(min,max){
	Random,out,Min,Max
	return out
}
Add_Border_Trim(Window,x,y,w,h,Color,Thickness:=1){
	y2:=y+h-Thickness,x2:=x+w-Thickness
	Gui,%Window%:Add,Progress,x%x% y%y% w%w% h%Thickness% Background%color%
	Gui,%Window%:Add,Progress,x%x% y%y% w%Thickness% h%h% Background%color%
	Gui,%Window%:Add,Progress,x%x% y%y2% w%w% h%Thickness% Background%color%
	Gui,%Window%:Add,Progress,x%x2% y%y% w%Thickness% h%h% Background%color%
}










;   The stuff below this line is not really part of the program (Mostly Gdip Functions)
;--------------------------------------------------------------------------------------------------------------------------------
;--------------------------------------------------------------------------------------------------------------------------------
; Gdip standard library v1.45 by tic (Tariq Porter) 07/09/11
; Modifed by Rseding91 using fincs 64 bit compatible Gdip library 5/1/2013
Class Progress_Button	{
	__New(Window_Name,Button_Name,Label,x,y,w,h,BC,TRC,TC1,TC2,TC3,Button_Text,Text_Offset:=0){
		This.Text_Offset:=Text_Offset,This.Window_Name:=Window_Name,This.Button_Name:=Button_Name,This.Label:=Label
		This.Button_ID1:=Button_Name "_1",This.Button_ID2:=Button_Name "_2",This.Button_ID3:=Button_Name "_3"
		This.Button_ID4:=Button_Name "_4",This.Button_Text:=Button_Text,This.X:=x,This.Y:=y,This.W:=w,This.H:=h 
		This.Bottom_Color:=BC,This.Trim_Color:=TRC,This.Top_Color_1:=TC1,This.Top_Color_2:=TC2,This.Top_Color_3:=TC3
		This.Add_Button()
	}
	Add_Button(){
		global
		Gui,% This.Window_Name ":Add",Text,% "x" This.X " y" This.Y " w" This.W " h" This.H " v" This.Button_Name " g" This.Label
		Gui,% This.Window_Name ":Add",Progress,% "x" This.X " y" This.Y " w" This.W " h" This.H " Background" This.Bottom_Color " v" This.Button_ID1
		Gui,% This.Window_Name ":Add",Progress,% "x" This.X " y" This.Y " w" This.W-1 " h" This.H-1 " Background" This.Trim_Color " v" This.Button_ID2
		Gui,% This.Window_Name ":Add",Progress,% "x" This.X+1 " y" This.Y+1 " w" This.W-2 " h" This.H-2 " Background" This.Top_Color_1 " v" This.Button_ID3
		Gui,% This.Window_Name ":Add",Text,% "x" This.X+1 " y" This.Y+This.Text_Offset " w" This.W-2 " r1 Center BackgroundTrans v" This.Button_ID4,% This.Button_Text
	}
	Button_Press(){
		global 
		Press_Active:=1
		GuiControl,% This.Window_Name ":Move",% This.Button_ID4,% "x" This.X+1 " y" This.Y+1+This.Text_Offset
		sleep,-1
		GuiControl,% This.Window_Name ":Hide",This.Button_ID2
		GuiControl,% This.Window_Name ":+Background" This.Top_Color_3,% This.Button_ID3
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID1
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID3
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID4
		While(GetKeyState("LButton"))
			Sleep, 10
		GuiControl,% This.Window_Name ":Show",This.Button_ID2
		GuiControl,% This.Window_Name ":Move",% This.Button_ID4,% "x" This.X " y" This.Y+This.Text_Offset
		GuiControl,% This.Window_Name ":+Background" This.Top_Color_1,% This.Button_ID3
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID1
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID2
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID3
		GuiControl,% This.Window_Name ":+Redraw",% This.Button_ID4
		sleep,10
	}
}	
Layered_Window_SetUp(Smoothing,Window_X,Window_Y,Window_W,Window_H,Window_Name:=1,Window_Options:=""){
	Layered:={},Layered.W:=Window_W,Layered.H:=Window_H,Layered.X:=Window_X,Layered.Y:=Window_Y,Layered.Name:=Window_Name
	Layered.Options:=Window_Options,Layered.Token:=Gdip_Startup(),Create_Layered_GUI(Layered)
	Layered.hwnd:=winExist(),Layered.hbm := CreateDIBSection(Window_W,Window_H)
	Layered.hdc := CreateCompatibleDC(),Layered.obm := SelectObject(Layered.hdc,Layered.hbm)
	Layered.G := Gdip_GraphicsFromHDC(Layered.hdc),Gdip_SetSmoothingMode(Layered.G,Smoothing)
	return Layered
}
Create_Layered_GUI(Layered){
	Gui,% Layered.Name ": +E0x80000 +LastFound " Layered.Options 
	Gui,% Layered.Name ":Show",% "x" Layered.X " y" Layered.Y " w" Layered.W " h" Layered.H " NA"
}	
Layered_Window_ShutDown(This){
	SelectObject(This.hdc,This.obm)
	DeleteObject(This.hbm)
	DeleteDC(This.hdc)
	gdip_deleteGraphics(This.g)
	Gdip_Shutdown(This.Token)
}
New_Brush(colour:="000000",Alpha:="FF"){
	static Hellbent_Brush:=[]
	new_colour := "0x" Alpha colour 
	Hellbent_Brush[Hellbent_Brush.Length()+1]:=Gdip_BrushCreateSolid(new_colour)
	return Hellbent_Brush[Hellbent_Brush.Length()]
}
Fill_Box(pGraphics,pBrush,x,y,w,h){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	return DllCall("gdiplus\GdipFillRectangle", Ptr, pGraphics, Ptr, pBrush, "float", x, "float", y, "float", w, "float", h)
}
Gdip_DeleteBrush(pBrush){
   return DllCall("gdiplus\GdipDeleteBrush", A_PtrSize ? "UPtr" : "UInt", pBrush)
}
DeleteObject(hObject){
   return DllCall("DeleteObject", A_PtrSize ? "UPtr" : "UInt", hObject)
}
UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	if ((x != "") && (y != ""))
		VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")
	if (w = "") ||(h = "")
		WinGetPos,,, w, h, ahk_id %hwnd%
	return DllCall("UpdateLayeredWindow", Ptr, hwnd, Ptr, 0, Ptr, ((x = "") && (y = "")) ? 0 : &pt, "int64*", w|h<<32, Ptr, hdc, "int64*", 0, "uint", 0, "UInt*", Alpha<<16|1<<24, "uint", 2)
}
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
}
Gdip_GraphicsFromImage(pBitmap){
	DllCall("gdiplus\GdipGetImageGraphicsContext", A_PtrSize ? "UPtr" : "UInt", pBitmap, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
	return pGraphics
}
Gdip_SetSmoothingMode(pGraphics, SmoothingMode){
   return DllCall("gdiplus\GdipSetSmoothingMode", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", SmoothingMode)
}
Gdip_TextToGraphics(pGraphics, Text, Options, Font="Arial", Width="", Height="", Measure=0){
	IWidth := Width, IHeight:= Height
	
	RegExMatch(Options, "i)X([\-\d\.]+)(p*)", xpos)
	RegExMatch(Options, "i)Y([\-\d\.]+)(p*)", ypos)
	RegExMatch(Options, "i)W([\-\d\.]+)(p*)", Width)
	RegExMatch(Options, "i)H([\-\d\.]+)(p*)", Height)
	RegExMatch(Options, "i)C(?!(entre|enter))([a-f\d]+)", Colour)
	RegExMatch(Options, "i)Top|Up|Bottom|Down|vCentre|vCenter", vPos)
	RegExMatch(Options, "i)NoWrap", NoWrap)
	RegExMatch(Options, "i)R(\d)", Rendering)
	RegExMatch(Options, "i)S(\d+)(p*)", Size)

	if !Gdip_DeleteBrush(Gdip_CloneBrush(Colour2))
		PassBrush := 1, pBrush := Colour2
	
	if !(IWidth && IHeight) && (xpos2 || ypos2 || Width2 || Height2 || Size2)
		return -1

	Style := 0, Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
	Loop, Parse, Styles, |
	{
		if RegExMatch(Options, "\b" A_loopField)
		Style |= (A_LoopField != "StrikeOut") ? (A_Index-1) : 8
	}
  
	Align := 0, Alignments := "Near|Left|Centre|Center|Far|Right"
	Loop, Parse, Alignments, |
	{
		if RegExMatch(Options, "\b" A_loopField)
			Align |= A_Index//2.1      ; 0|0|1|1|2|2
	}

	xpos := (xpos1 != "") ? xpos2 ? IWidth*(xpos1/100) : xpos1 : 0
	ypos := (ypos1 != "") ? ypos2 ? IHeight*(ypos1/100) : ypos1 : 0
	Width := Width1 ? Width2 ? IWidth*(Width1/100) : Width1 : IWidth
	Height := Height1 ? Height2 ? IHeight*(Height1/100) : Height1 : IHeight
	if !PassBrush
		Colour := "0x" (Colour2 ? Colour2 : "ff000000")
	Rendering := ((Rendering1 >= 0) && (Rendering1 <= 5)) ? Rendering1 : 4
	Size := (Size1 > 0) ? Size2 ? IHeight*(Size1/100) : Size1 : 12

	hFamily := Gdip_FontFamilyCreate(Font)
	hFont := Gdip_FontCreate(hFamily, Size, Style)
	FormatStyle := NoWrap ? 0x4000 | 0x1000 : 0x4000
	hFormat := Gdip_StringFormatCreate(FormatStyle)
	pBrush := PassBrush ? pBrush : Gdip_BrushCreateSolid(Colour)
	if !(hFamily && hFont && hFormat && pBrush && pGraphics)
		return !pGraphics ? -2 : !hFamily ? -3 : !hFont ? -4 : !hFormat ? -5 : !pBrush ? -6 : 0
   
	CreateRectF(RC, xpos, ypos, Width, Height)
	Gdip_SetStringFormatAlign(hFormat, Align)
	Gdip_SetTextRenderingHint(pGraphics, Rendering)
	ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)

	if vPos
	{
		StringSplit, ReturnRC, ReturnRC, |
		
		if (vPos = "vCentre") || (vPos = "vCenter")
			ypos += (Height-ReturnRC4)//2
		else if (vPos = "Top") || (vPos = "Up")
			ypos := 0
		else if (vPos = "Bottom") || (vPos = "Down")
			ypos := Height-ReturnRC4
		
		CreateRectF(RC, xpos, ypos, Width, ReturnRC4)
		ReturnRC := Gdip_MeasureString(pGraphics, Text, hFont, hFormat, RC)
	}

	if !Measure
		E := Gdip_DrawString(pGraphics, Text, hFont, hFormat, pBrush, RC)

	if !PassBrush
		Gdip_DeleteBrush(pBrush)
	Gdip_DeleteStringFormat(hFormat)   
	Gdip_DeleteFont(hFont)
	Gdip_DeleteFontFamily(hFamily)
	return E ? E : ReturnRC
}
Gdip_DeleteGraphics(pGraphics){
   return DllCall("gdiplus\GdipDeleteGraphics", A_PtrSize ? "UPtr" : "UInt", pGraphics)
}
Gdip_DrawImage(pGraphics, pBitmap, dx="", dy="", dw="", dh="", sx="", sy="", sw="", sh="", Matrix=1){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	if (Matrix&1 = "")
		ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
	else if (Matrix != 1)
		ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")
	if (sx = "" && sy = "" && sw = "" && sh = "")
	{
		if (dx = "" && dy = "" && dw = "" && dh = "")
		{
			sx := dx := 0, sy := dy := 0
			sw := dw := Gdip_GetImageWidth(pBitmap)
			sh := dh := Gdip_GetImageHeight(pBitmap)
		}
		else
		{
			sx := sy := 0
			sw := Gdip_GetImageWidth(pBitmap)
			sh := Gdip_GetImageHeight(pBitmap)
		}
	}
	E := DllCall("gdiplus\GdipDrawImageRectRect"
				, Ptr, pGraphics
				, Ptr, pBitmap
				, "float", dx
				, "float", dy
				, "float", dw
				, "float", dh
				, "float", sx
				, "float", sy
				, "float", sw
				, "float", sh
				, "int", 2
				, Ptr, ImageAttr
				, Ptr, 0
				, Ptr, 0)
	if ImageAttr
		Gdip_DisposeImageAttributes(ImageAttr)
	return E
}
Gdip_Startup(){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
		DllCall("LoadLibrary", "str", "gdiplus")
	VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
	return pToken
}
CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	hdc2 := hdc ? hdc : GetDC()
	VarSetCapacity(bi, 40, 0)
	NumPut(w, bi, 4, "uint")
	, NumPut(h, bi, 8, "uint")
	, NumPut(40, bi, 0, "uint")
	, NumPut(1, bi, 12, "ushort")
	, NumPut(0, bi, 16, "uInt")
	, NumPut(bpp, bi, 14, "ushort")
	hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, "uint", 0, A_PtrSize ? "UPtr*" : "uint*", ppvBits, Ptr, 0, "uint", 0, Ptr)
	if !hdc
		ReleaseDC(hdc2)
	return hbm
}
CreateCompatibleDC(hdc=0){
   return DllCall("CreateCompatibleDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
SelectObject(hdc, hgdiobj){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
}
Gdip_GraphicsFromHDC(hdc){
    DllCall("gdiplus\GdipCreateFromHDC", A_PtrSize ? "UPtr" : "UInt", hdc, A_PtrSize ? "UPtr*" : "UInt*", pGraphics)
    return pGraphics
}
DeleteDC(hdc){
   return DllCall("DeleteDC", A_PtrSize ? "UPtr" : "UInt", hdc)
}
Gdip_Shutdown(pToken){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
	if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
		DllCall("FreeLibrary", Ptr, hModule)
	return 0
}
Gdip_BrushCreateSolid(ARGB=0xff000000){
	DllCall("gdiplus\GdipCreateSolidFill", "UInt", ARGB, A_PtrSize ? "UPtr*" : "UInt*", pBrush)
	return pBrush
}
Gdip_CloneBrush(pBrush){
	DllCall("gdiplus\GdipCloneBrush", A_PtrSize ? "UPtr" : "UInt", pBrush, A_PtrSize ? "UPtr*" : "UInt*", pBrushClone)
	return pBrushClone
}
Gdip_FontFamilyCreate(Font){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	if (!A_IsUnicode){
		nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, "uint", 0, "int", 0)
		VarSetCapacity(wFont, nSize*2)
		DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &Font, "int", -1, Ptr, &wFont, "int", nSize)
	}
	DllCall("gdiplus\GdipCreateFontFamilyFromName", Ptr, A_IsUnicode ? &Font : &wFont, "uint", 0, A_PtrSize ? "UPtr*" : "UInt*", hFamily)
	return hFamily
}
Gdip_FontCreate(hFamily, Size, Style=0){
   DllCall("gdiplus\GdipCreateFont", A_PtrSize ? "UPtr" : "UInt", hFamily, "float", Size, "int", Style, "int", 0, A_PtrSize ? "UPtr*" : "UInt*", hFont)
   return hFont
}
Gdip_StringFormatCreate(Format=0, Lang=0){
   DllCall("gdiplus\GdipCreateStringFormat", "int", Format, "int", Lang, A_PtrSize ? "UPtr*" : "UInt*", hFormat)
   return hFormat
}
CreateRectF(ByRef RectF, x, y, w, h){
   VarSetCapacity(RectF, 16)
   NumPut(x, RectF, 0, "float"), NumPut(y, RectF, 4, "float"), NumPut(w, RectF, 8, "float"), NumPut(h, RectF, 12, "float")
}
Gdip_SetStringFormatAlign(hFormat, Align){
   return DllCall("gdiplus\GdipSetStringFormatAlign", A_PtrSize ? "UPtr" : "UInt", hFormat, "int", Align)
}
Gdip_SetTextRenderingHint(pGraphics, RenderingHint){
	return DllCall("gdiplus\GdipSetTextRenderingHint", A_PtrSize ? "UPtr" : "UInt", pGraphics, "int", RenderingHint)
}
Gdip_MeasureString(pGraphics, sString, hFont, hFormat, ByRef RectF){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	VarSetCapacity(RC, 16)
	if !A_IsUnicode
	{
		nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, "uint", 0, "int", 0)
		VarSetCapacity(wString, nSize*2)   
		DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
	}
	DllCall("gdiplus\GdipMeasureString", Ptr, pGraphics, Ptr, A_IsUnicode ? &sString : &wString, "int", -1, Ptr, hFont, Ptr, &RectF, Ptr, hFormat, Ptr, &RC, "uint*", Chars, "uint*", Lines)
	return &RC ? NumGet(RC, 0, "float") "|" NumGet(RC, 4, "float") "|" NumGet(RC, 8, "float") "|" NumGet(RC, 12, "float") "|" Chars "|" Lines : 0
}
Gdip_DrawString(pGraphics, sString, hFont, hFormat, pBrush, ByRef RectF){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	if (!A_IsUnicode){
		nSize := DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, 0, "int", 0)
		VarSetCapacity(wString, nSize*2)
		DllCall("MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sString, "int", -1, Ptr, &wString, "int", nSize)
	}
	return DllCall("gdiplus\GdipDrawString", Ptr, pGraphics, Ptr, A_IsUnicode ? &sString : &wString, "int", -1, Ptr, hFont, Ptr, &RectF, Ptr, hFormat, Ptr, pBrush)
}
Gdip_DeleteStringFormat(hFormat){
   return DllCall("gdiplus\GdipDeleteStringFormat", A_PtrSize ? "UPtr" : "UInt", hFormat)
}
Gdip_DeleteFont(hFont){
   return DllCall("gdiplus\GdipDeleteFont", A_PtrSize ? "UPtr" : "UInt", hFont)
}
Gdip_DeleteFontFamily(hFamily){
   return DllCall("gdiplus\GdipDeleteFontFamily", A_PtrSize ? "UPtr" : "UInt", hFamily)
}
Gdip_SetImageAttributesColorMatrix(Matrix){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	VarSetCapacity(ColourMatrix, 100, 0)
	Matrix := RegExReplace(RegExReplace(Matrix, "^[^\d-\.]+([\d\.])", "$1", "", 1), "[^\d-\.]+", "|")
	StringSplit, Matrix, Matrix, |
	Loop, 25	{
		Matrix := (Matrix%A_Index% != "") ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
		NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "float")
	}
	DllCall("gdiplus\GdipCreateImageAttributes", A_PtrSize ? "UPtr*" : "uint*", ImageAttr)
	DllCall("gdiplus\GdipSetImageAttributesColorMatrix", Ptr, ImageAttr, "int", 1, "int", 1, Ptr, &ColourMatrix, Ptr, 0, "int", 0)
	return ImageAttr
}
Gdip_GetImageWidth(pBitmap){
   DllCall("gdiplus\GdipGetImageWidth", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Width)
   return Width
}
Gdip_GetImageHeight(pBitmap){
   DllCall("gdiplus\GdipGetImageHeight", A_PtrSize ? "UPtr" : "UInt", pBitmap, "uint*", Height)
   return Height
}
Gdip_DisposeImageAttributes(ImageAttr){
	return DllCall("gdiplus\GdipDisposeImageAttributes", A_PtrSize ? "UPtr" : "UInt", ImageAttr)
}
GetDC(hwnd=0){
	return DllCall("GetDC", A_PtrSize ? "UPtr" : "UInt", hwnd)
}
ReleaseDC(hdc, hwnd=0){
	Ptr := A_PtrSize ? "UPtr" : "UInt"
	return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
}
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Looking for efficiency tips related to working with graphics.

23 Jun 2018, 12:28

GDI - though less powerful is better than GDI+ for real time graphics.
If you want even more speed you should probably look into OpenGL or DirectX.
Recommends AHK Studio

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 238 guests