- Calling BufferAlloc() first and returning a pointer.
- Using that pointer as the Scan0 inside the BitmapData (16) of a GdipBitmapLockBits call. (0x7)
- And overriding the meta functions such as __Item to perform NumGet on bitmap[x, y] pixel values.
BITMAP class? Topic is solved
BITMAP class?
Would it be possible to create a bitmap class using the new BufferAlloc syntax? I'd imagine that a GDI+ Bitmap class could be done. Would probably require:
Re: BITMAP class? Topic is solved
im rusty on gdi and i dont recall what exactly goes into locking bits, but the following pattern should be applicable either way
Code: Select all
#Requires AutoHotkey v2.0-a133-9819cb2d
class Bitmap
{
; statics are for internal use only; dont call.
; these are here to provide a place for fetching
; method references and reduce duplication
; but u could implement something else instead, too
; assume .LockBits() has been called
static __Item_Get_Locked(x, y) {
return 0xFF00FF ; some color ud get from running NumGet
}
; assume .LockBits() has been called
static __Item_Set_Locked(value, x, y) {
return value ; some color ud set NumPut
}
; assume bits are unlocked
static __Item_Get_Unlocked(x, y) {
; the first time 'Bmp[x, y]' is invoked in AHK code,
; "when it is being used in AHK it should lock the bits"
this.LockBits()
return this[x, y] ; invokes the now-replaced, unchecked procedure
}
; assume bits are unlocked
static __Item_Set_Unlocked(value, x, y) {
this.LockBits()
return this[x, y] := value
}
__New(w, h) {
this.Buf := Buffer(w * h * 32)
this.IsLocked := false
; have to set up metaitem in the constructor here,
; since the object doesnt yet have one
static PropDesc := {Get: Bitmap.__Item_Get_Unlocked, Set: Bitmap.__Item_Set_Unlocked}
this.DefineProp('__Item', PropDesc)
}
; assume "when the object is transported into a GDI+ function it should unlock the bits"
; to be true, since something(eg DllCall) is querying the .Ptr property
Ptr {
get {
if this.IsLocked
this.UnlockBits()
return this.Buf.Ptr ; return the ptr of the internal buffer backing the bitmap
}
set {
if this.IsLocked
this.UnlockBits()
return this.Buf.Ptr := value
}
; same pattern as for __Item can be applied instead to get rid of the if-checking
}
; avoid defining Bitmap.Prototype.__Item
; __Item[x, y] {
; ...
; }
LockBits() {
if this.IsLocked ; do nothing if already locked
return
this.IsLocked := true
; replace metaitem with an unchecked version of the method
; this saves u having to check a flag(eg .IsLocked) every time
; which would result in reduced performance, since __Item would
; most often be used in hotloops and ud be wasting cycles on what
; u already know to be true
static PropDesc := {Get: Bitmap.__Item_Get_Locked, Set: Bitmap.__Item_Set_Locked}
; important to define the instance method on the instance itself!,
; instead of on Bitmap.Prototype (ie 'this.Base.DefineProp...'),
; since multiple bitmaps could be instantiated at a time and we
; want them to keep track of their locked/unlock states themselves
this.DefineProp('__Item', PropDesc)
MsgBox 'bits are LOCKED'
}
UnlockBits() {
if !this.IsLocked ; do nothing if already unlocked
return
this.IsLocked := false
static PropDesc := {Get: Bitmap.__Item_Get_Unlocked, Set: Bitmap.__Item_Set_Unlocked}
this.DefineProp('__Item', PropDesc)
MsgBox 'bits are UNlocked'
}
}
Bmp := Bitmap(100, 200)
MsgBox Bmp[15, 60] ; automatically locks
MsgBox Bmp[15, 60] := 0x0000FF ; automatically locks(unless already locked)
MsgBox gdiplusFunction(Bmp) ; automatically unlocks
MsgBox Bmp[15, 60] ; automatically re-locks
gdiplusFunction(BitmapInstance) {
; dllcalls taking Ptr types, accept Object and query their .Ptr property automatically
; DllCall(.., 'Ptr', BitmapInstance, ...)
return BitmapInstance.Ptr ; so simulate that behavior here
}
Who is online
Users browsing this forum: Descolada and 24 guests