Moin,
Andy und ich haben in der letzten Zeit viel an Assemblerfunktionen herumgebastelt. Die Resultate schwankten von Super toll bis kaum brauchbar^^
Vermutlich sind wir aber nicht die einzigen die gerne mal eine (kleine) Asm Funktion basteln. Oft läuft das was gebaut wird redundant, weil keiner von den Erfolgen der Anderen weiß.
Wäre es sinnvoll eine Sammelstelle für scheinbar nur ganz speziell nutzbare Asm Codes zu erstellen ?
Die Erfahrung (und Logik) zeigt: Schnell ist nur was speziell für das, wofür es benötigt wird, zugeschnitten ist. Eine Funktion die mehr kann als sie muss ist also immer suboptimal.
Wenn genügend Funktionen zusammenfinden ist es aber möglich für jedes Problem eine (halbwegs) passende Funktion zu finden.
Ein weiterer Vorteil wäre, dass man über fremde Codes mal drüberschauen kann und ggf Verbesserungen vornehmen kann. So können auch weniger begabte AsmFanatiker ihren Beitrag liefern. Mit etwas Glück versteht einer der besseren das Prinzip der Funktion und kann es ggf optimieren.
Ich habe mal angefangen ein paar meiner Funktionen in eine halbwegs nutzbare Form zu bringen, sodass sie (nach einigen Tests) fehlerfrei laufen. (asm stürzt ja idr öfters ab als alles andere^^).
Ziel ist nicht nur der Geschwindigkeitsvorteil, sondern auch der Spaß am Unmöglichen.
Und ganz nebenbei kann man noch eine Menge über seinen Computer lernen und wie er arbeitet.
Was haltet ihr von der Idee ?
Inhalte
Anhang:
- MemoryDll.au3
- FASM.au3
- AssembleIt.au3
- ASMGfx.au3 (mal ganz provisorisch zusammengebastelt)
- Beispiel.au3 (Vergleich GDI(+) / ASM in einem aus Commander Keen bekannten Minispiel)
Bisherige Funktionen:
- StretchBlt ( Nur mit dem Zoomfaktor 2) - Skaliert ein Bild auf 2Fache Größe
- FillRect ( Noch nicht komplett in ASM übersetzt. Kein SSE. langsamer als GDI+ ) - Füllt ein Rechteck mit nichttransparenter Farbe
- SwapColors - Ersetzt eine Farbe in einem Bild durch eine andere (gut um Schrift zu färben)
- ClearBitmap - Ersatz für GraphicsClear oder BitBlt mit BLACKNESS
- MoveMemory - Ersatz für BitBlt wenn X = Y = 0 und beide Bilder gleich groß sind.
asm.au3
#include <GDIPlus.au3>
#include <AssembleIt.au3>
; Struct Array
Global $___avOP[1]
; DLLs
Global $___ASM_DLL_USER32, $___ASM_DLL_GDI32
; ASM Func Positions
Global $___ASM_OP_StretchBlt_Zoom_2, $___ASM_OP_Fill_Rect, $___ASM_OP_Swap_Colors, $___ASM_OP_Clear_Bitmap, $___ASM_OP_Move_Memory
#region - Public
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Move_Memory
; Description ...: Kopiert einen Teil im RAM an eine andere Stelle.
; Syntax.........: _ASM_Move_Memory($Ptr_Ziel, $Ptr_Quelle, $iBytes)
; Parameters ....: $Ptr_Ziel - Position im Ram an die geschrieben werden soll
; $Ptr_Quelle - Position im Ram von der gelesen werden soll
; $iQBytes - Anzahl QBytes die kopiert werden sollen (1 QByte = 4 Byte = 32Bit)
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......: Der zu kopierende Speicher muss mindestens 37 Byte enthalten.
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_MoveMemory($Ptr_Ziel, $Ptr_Quelle, $iQBytes)
DllCall($___ASM_DLL_USER32, 'ptr', 'CallWindowProcW', 'ptr', DllStructGetPtr($___avOP[$___ASM_OP_Move_Memory]), 'ptr', $Ptr_Ziel, 'ptr', $Ptr_Quelle, 'int', $iQBytes, 'int', 0)
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Clear_Bitmap
; Description ...: Füllt alle Pixel eines Bildes mit der angegebenen Farbe
; Syntax.........: _ASM_Clear_Bitmap($vImg, $iCol)
; Parameters ....: $vImg - DllStruct die ein Bild incl Zusatzdaten enthält (_Image_Create...)
; $iCol - Farbe mit der alle Pixel gefärbt werden sollen
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......: Das zu clearende Bild muss mindestens 17 Pixel enthalten.
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_ClearBitmap($vImg, $iCol)
DllCall($___ASM_DLL_USER32, 'ptr', 'CallWindowProcW', 'ptr', DllStructGetPtr($___avOP[$___ASM_OP_Clear_Bitmap]), 'ptr', DllStructGetData($vImg, 1, 4), 'ptr', DllStructGetData($vImg, 1, 2)*DllStructGetData($vImg, 1, 3), 'int', $iCol, 'int', 0)
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Swap_Colors
; Description ...: Ersetzt die gesuchte Farbe durch eine beliebige andere. (Transparenz wird unterstützt)
; Syntax.........: _ASM_Swap_Colors($vImg, $iCol1, $iCol2)
; Parameters ....: $vImg - DllStruct die ein Bild incl Zusatzdaten enthält (_Image_Create...)
; $iCol1 - Farbe die ersetzt werden soll
; $iCol2 - Farbe mit der ersetzt wird
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_SwapColors($vImg, $iCol1, $iCol2)
DllCall($___ASM_DLL_USER32, 'ptr', 'CallWindowProcW', 'ptr', DllStructGetPtr($___avOP[$___ASM_OP_Swap_Colors]), 'ptr', DllStructGetData($vImg, 1, 4), 'ptr', $iCol1, 'int', $iCol2, 'int', DllStructGetData($vImg, 1, 2)*DllStructGetData($vImg, 1, 3))
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Fill_Rect
; Description ...: Füllt ein Rechteck auf dem Zielbild mit der angegebenen Farbe. Transparenz wird nicht unterstützt.
; Syntax.........: _ASM_Fill_Rect($vImg_Dest, $iX, $iY, $iW, $iH, $iCol)
; Parameters ....: $vImg_Dest - DllStruct die ein Bild incl Zusatzdaten enthält (_Image_Create...)
; $iX - x Koordinate der oberen Linken Ecke des Vierecks
; $iY - y Koordinate der oberen Linken Ecke des Vierecks
; $iW - Breite des Vierecks
; $iH - Höhe des Vierecks
; $iCol - Farbe des Rechtecks in 0xAARRGGBB Format. (Transparenz wird nur mit angegeben um im 32Bit Format zu bleiben)
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......: Die Funktion ist noch unvollständig in ASM übersetzt worden.
; Einige Berechnungen werden also noch in AutoIt durchgeführt.
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_FillRect($vImg_Dest, $iX, $iY, $iW, $iH, $iCol)
Local $iMaxW = DllStructGetData($vImg_Dest, 1, 2) ; Breite des Zielbildes
Local $iMaxH = DllStructGetData($vImg_Dest, 1, 3) ; Höhe des Zielbildes
; Situation:
; X und Y Koordinaten können überall, auch außerhalb liegen
; Breite und Höhe sind eventuell kleiner als 0.
; Das Rechteck passt eventuell nicht vollständig auf das Zielbild.
; --> Es wird nur ein Ausschnitt des Rechtecks gezeichnet.
If $iX >= $iMaxW Then Return ; X liegt rechts neben dem Bild - Rechteck in jedem Fall außerhalb
If $iY >= $iMaxH Then Return ; Y liegt unter dem Bild - Rechteck in jedem Fall außerhalb
If $iX < 0 Then ; X liegt links neben dem Bild
$iW -= Abs($iX) ; Rechteck eventuell innerhalb
If $iW <= 0 Then Return ; Das Bild lag zu weit links...
$iX = 0
EndIf
If $iY < 0 Then ; Y liegt über dem Bild
$iH -= Abs($iH) ; Rechteck eventuell innterhalb
If $iH <= 0 Then Return ; Das Bild lag zu weit oben...
$iY = 0
EndIf
; Jetzt sind X und Y innerhalb des Bildes und W und H größer 0
; Ist das Rechteck denn auch Passend ?
; Wenn nicht --> Zuschneiden !
If $iW+$iX > $iMaxW Then $iW = $iMaxW - $iX ; Zu breit
If $iH+$iY > $iMaxH Then $iH = $iMaxH - $iY ; Zu hoch
If $iW <= 0 Then Return
If $iH <= 0 Then Return
Local Static $vStruct = DllStructCreate('int[7]') ; Parameter für den ASM Code
DllStructSetData($vStruct, 1, $iX, 1) ; X
DllStructSetData($vStruct, 1, $iY, 2) ; Y
DllStructSetData($vStruct, 1, $iW, 3) ; W
DllStructSetData($vStruct, 1, $iH, 4) ; H
DllStructSetData($vStruct, 1, $iMaxW, 5) ; Bildbreite
;~ DllStructSetData($vStruct, 1, $iMaxH, 6) ; Bildhöhe
DllStructSetData($vStruct, 1, $iCol, 6) ; Farbe
DllCall($___ASM_DLL_USER32, 'ptr', 'CallWindowProcW', 'ptr', DllStructGetPtr($___avOP[$___ASM_OP_Fill_Rect]), 'ptr', DllStructGetData($vImg_Dest, 1, 4), 'ptr', DllStructGetPtr($vStruct), 'int', 0, 'int', 0)
[/autoit] [autoit][/autoit] [autoit]EndFunc
[/autoit] [autoit][/autoit] [autoit]; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_StretchBlt_Zoom_2
; Description ...: Vergrößert das Quellbild um den Faktor 2 und bildet es auf das Zielbild ab.
; Syntax.........: _ASM_StretchBlt_Zoom_2($vImg_Dest, $vImg_Source)
; Parameters ....: $vImg_Dest - DllStruct die ein Bild incl Zusatzdaten enthält (_Image_Create...)
; $vImg_Source - DllStruct die ein Bild incl Zusatzdaten enthält (_Image_Create...)
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......: Das Zielbild muss exakt die doppelte Breite, sowie die doppelte Höhe des Quellbildes besitzen.
; Der Interpolationsmodus ist Nearest Neighbour
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_StretchBlt_Zoom2($vImg_Dest, $vImg_Source)
DllCall($___ASM_DLL_USER32, 'ptr', 'CallWindowProcW', 'ptr', DllStructGetPtr($___avOP[$___ASM_OP_StretchBlt_Zoom_2]), 'ptr', DllStructGetData($vImg_Dest, 1, 4), 'ptr', DllStructGetData($vImg_Source, 1, 4), 'int', DllStructGetData($vImg_Source, 1, 2), 'int', DllStructGetData($vImg_Source, 1, 3))
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Startup
; Description ...: Läd nötige DLLs und initialisiert alle OP-Codes für die spätere Benutzung.
; Syntax.........: _ASM_Startup()
; Parameters ....:
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......: _ASM_Shutdown
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_Startup()
; Erstmal ein Reset
FasmReset($Fasm)
; DLLs starten
$___ASM_DLL_USER32 = DllOpen('USER32.DLL')
$___ASM_DLL_GDI32 = DllOpen('GDI32.DLL')
; Jede Funktion kann nach dem Schema eingefügt werden.
; Alle ASM Codes werden als Struct in einem Array gelagert.
$___ASM_OP_StretchBlt_Zoom_2 = __ASM_Add_OP(__ASM_Stretch_Zoom_2())
$___ASM_OP_Fill_Rect = __ASM_Add_OP(__ASM_Fill_Rect())
$___ASM_OP_Swap_Colors = __ASM_Add_OP(__ASM_Swap_Colors())
$___ASM_OP_Clear_Bitmap = __ASM_Add_OP(__ASM_Clear_Bitmap())
$___ASM_OP_Move_Memory = __ASM_Add_OP(__ASM_Move_Memory())
EndFunc
[/autoit] [autoit][/autoit] [autoit]; #FUNCTION# ====================================================================================================================
; Name...........: _ASM_Shutdown
; Description ...: Gibt die Ressourcen wieder frei.
; Syntax.........: _ASM_Shutdown()
; Parameters ....:
; Return values .:
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......: _ASM_Startup
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _ASM_Shutdown()
; Structs leeren
For $i = 1 To $___avOP[0] Step 1
$___avOP[$i] = 0
Next
; DLLs schließen
DllClose($___ASM_DLL_USER32)
EndFunc
[/autoit] [autoit][/autoit] [autoit]#endregion - Public
[/autoit] [autoit][/autoit] [autoit]#region - Internal
[/autoit] [autoit][/autoit] [autoit]; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __ASM_Add_OP
; Description ...: Fügt OP-Codes zum Struct Array hinzu
; Syntax.........: __ASM_Add_OP($a)
; Parameters ....: $a - Dieser Parameter ermöglicht das kompakte Aufrufen der ASM Funktion die hinzugefügt werden soll.
; Return values .: Aktueller OP-Index. (Zufriff auf ASM Ops über diesen Index möglich)
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __ASM_Add_OP($a)
Local $vOP = __ASM_GetStruct()
Local $u = UBound($___avOP)
ReDim $___avOP[$u+1]
$___avOP[0] += 1
$___avOP[$u] = $vOP
Return $___avOP[0]
EndFunc
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __ASM_GetStruct
; Description ...: Verpackt den in Fasm befindlichen Code in eine DllStruct die per CallWindowProc aufgerufen werden kann.
; Syntax.........: __ASM_GetStruct()
; Parameters ....:
; Return values .: $vStruct - Die DllStruct beinhaltet den ASM-Code
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __ASM_GetStruct()
Local $vStruct = __ASM_ToStruct(FasmGetBinary($Fasm))
FasmReset($Fasm)
Return $vStruct
EndFunc ;==>_Get_ASM_Struct
; #INTERNAL_USE_ONLY# ===========================================================================================================
; Name...........: __ASM_ToStruct
; Description ...: Verpackt den im Parameter enthaltenen Code in eine DLLStruct
; Syntax.........: __ASM_ToStruct($ASM)
; Parameters ....: $ASM - ASM Code
; Return values .: $vStr - Die DllStruct beinhaltet den Code aus $ASM
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func __ASM_ToStruct($ASM)
Local $vStr = DllStructCreate('byte[' & StringLen($ASM) / 2 - 1 & ']')
DllStructSetData($vStr, 1, $ASM)
Return $vStr
EndFunc ;==>_AsmToStruct
#endregion - Internal
[/autoit] [autoit][/autoit] [autoit]#region - ASM
[/autoit] [autoit][/autoit] [autoit]Func __ASM_Move_Memory()
_('use32')
_('mov edi, [esp+4]') ; Ptr Ziel
_('mov esi, [esp+8]') ; Ptr Quelle
_('mov ecx, [esp+12]') ; Anzahl Pixel
_('mov eax, edi') ;
_('sub eax, esi') ; eax = Abstand Ziel und Quellbitmap im Ram
_('sub ecx, 32') ; 32 Px schritte
_('align 16')
_('_px32:') ; 32Px - Schleife
_('movdqa xmm0, [esi]')
_('movdqa xmm1, [esi+16]')
_('movdqa xmm2, [esi+32]')
_('movdqa xmm3, [esi+48]')
_('movdqa xmm4, [esi+64]')
_('movdqa xmm5, [esi+80]')
_('movdqa xmm6, [esi+96]')
_('movdqa xmm7, [esi+112]')
_('movdqa [esi+eax], xmm0')
_('movdqa [esi+eax+16], xmm1')
_('movdqa [esi+eax+32], xmm2')
_('movdqa [esi+eax+48], xmm3')
_('movdqa [esi+eax+64], xmm4')
_('movdqa [esi+eax+80], xmm5')
_('movdqa [esi+eax+96], xmm6')
_('movdqa [esi+eax+112], xmm7')
_('add esi, 128')
_('sub ecx, 32')
_('ja _px32')
_('add ecx, 28') ; add 32 und sub 4
_('_px4:') ; 4px Schleife
_('movdqa xmm0, [esi]')
_('movdqa [esi+eax], xmm0')
_('add esi, 16')
_('sub ecx, 4')
_('ja _px4')
_('add ecx, 4')
_('_px1:') ; 1px Schleife
_('mov ebx, [esi]')
_('mov [esi+eax], ebx')
_('add esi, 4')
_('dec ecx')
_('ja _px1')
_('ret')
EndFunc ;==>__ASM_Move_Memory
Func __ASM_Clear_Bitmap()
_('use32')
_('mov edi, [esp+4]') ; ptr
_('mov ebx, [esp+12]') ; col
_('mov ecx, [esp+8]') ; px
_('movd xmm0,ebx') ; xmm0 = col
_('punpckldq xmm0,xmm0') ; xmm0 = col|col
_('punpckldq xmm0,xmm0') ; xmm0 = col|col|col|col
_('sub ecx, 32') ; 32px weniger füllen (ermöglicht beliebige Breite und Höhe trotz SSE) Die Grafik muss aber mindestens 16(+1)px besitzen. Sonst schlägt der clear fehl.
_('_Schleife:')
_('movdqa [edi], xmm0')
_('movdqa [edi+16], xmm0')
_('movdqa [edi+32], xmm0')
_('movdqa [edi+48], xmm0')
_('movdqa [edi+64], xmm0')
_('movdqa [edi+80], xmm0')
_('movdqa [edi+96], xmm0')
_('movdqa [edi+112], xmm0')
_('add edi,128')
_('sub ecx, 32') ; 16px Schritte
_('ja _Schleife')
_('add ecx, 28')
_('_px4:') ; 4px Schleife
_('movdqa [edi], xmm0')
_('add edi, 16')
_('sub ecx, 4')
_('ja _px4')
_('add ecx, 4')
_('_px:') ; die letzten maximal 16 Pixel füllen
_('mov [edi], ebx')
_('add edi, 4')
_('dec ecx') ; 1px Schritte
_('ja _px')
_('ret ')
EndFunc
Func __ASM_Swap_Colors()
_('use32')
_('mov edi, [esp+4]') ; Bitmap
_('mov ebx, [esp+8]') ; Suchfarbe
_('mov edx, [esp+12]') ; ersetzfarbe
_('mov ecx, [esp+16]') ; anzahl Pixel
_('_Px:')
_('cmp [edi], ebx') ; Zielfarbe gefunden ?
_('jne _weiter') ; neee dann weiter
_('mov [edi], edx') ; jaaa dann ersetzen !
_('_weiter:') ; weiter
_('add edi, 4') ; 1px nach vorne
_('dec ecx')
_('jnz _Px')
_('ret')
EndFunc
Func __ASM_Fill_Rect()
_('use32')
_('mov esi, [esp+4]') ; ptr - Zielbitmap
_('mov edx, [esp+8]') ; ptr - Datenstruct
_('mov edi, [edx]') ; edi = X
_('mov ecx, [edx+4]') ; ecx = Y
_('mov ebx, [edx+8]') ; Viereck Breite
_('movd xmm0, [edx+12]') ; Viereck Höhe
_('mov eax, [edx+16]') ; Bild Breite
_('movd xmm1, [edx+20]') ; Farbe
_('imul ecx, eax') ; Y * Bildbreite
_('add edi, ecx')
_('shl edi, 2')
_('add edi, esi') ; edi = Pixelpos
_('shl eax, 2') ; eax = Anzahl Bytes in einer Reihe des Ziels
_('shl ebx, 2') ; ebx = Anzahl Bytes in einer Reihe des Vierecks
_('sub eax, ebx') ; eax = Differenz zwischen dem letzten px einer Reihe und dem ersten der Nächsten.
_('shr ebx, 2') ; ebx = Anzahl Px in einer Reihe
_('movd esi, xmm1')
_('movd ecx, xmm0') ; ecx = Reihen die abgearbeitet werden müssen !
_('_X:')
_('push ecx') ; ecx = verbleibende Reihen.
_('mov ecx, ebx') ; ecx wieder auf Viereckbreite setzen
_('_Y:') ; innerer Loop (kleiner gehts nicht...)
_('mov dword[edi], esi')
_('add edi, 4')
_('dec ecx')
_('jnz _Y')
_('add edi, eax') ; eine Reihe nach unten
_('pop ecx')
_('dec ecx')
_('jnz _X')
_('ret')
EndFunc
Func __ASM_Stretch_Zoom_2()
_('use32')
_('mov edi, [esp+4]')
_('mov esi, [esp+8]')
_('mov eax, [esp+12]')
_('mov ecx, [esp+16]')
_('movd xmm0, eax')
_('shl eax, 3')
_('movd xmm2, eax')
_('_Y:')
_('mov eax, ecx')
_('push ecx')
_('movd ecx, xmm0')
_('_X:')
_('push eax')
_('mov ebx, ecx')
_('dec eax')
_('dec ebx')
_('push eax')
_('movd xmm3, ecx') ; ecx sichern (push/pop geht nicht hier)
_('movd ecx, xmm0') ; ecx =breite
_('imul eax, ecx') ; Mal Breite.
_('add eax, ebx')
_('shl eax, 2')
_('movd xmm1, [eax+esi]') ; Farbe in xmm1 eax+esi = Pixelpos im Quellbild.
_('punpckldq xmm1, xmm1') ; Farbe|Farbe
_('pop edx')
_('shl edx, 4')
_('imul edx, ecx') ; Mal Breite
_('movd ecx, xmm3') ; Ecx wieder herstellen
_('shl ebx, 3')
_('add edx, ebx')
_('add edx, edi') ; Zielposition
_('movq [edx], xmm1') ; 2 Px schreiben
_('movd eax, xmm2') ; eax = Breite * 4 * 2px
_('movq [edx+eax], xmm1') ; 2Px schreiben
_('pop eax')
_('dec ecx')
_('jnz _X')
_('pop ecx')
_('dec ecx')
_('jnz _Y')
_('ret')
EndFunc ;==>__ASM_Stretch_Z2
#endregion - ASM
[/autoit] [autoit][/autoit] [autoit]#region - Teile der ImageUDF zum erstellen ASM kompatibeler Bilder
[/autoit] [autoit][/autoit] [autoit]; #FUNCTION# ;===============================================================================
; Name...........: _Image_Create
; Description ...: Creates an empty Image
; Syntax.........: _Image_Create($iW, $iH)
; Parameters ....: $iW - Width of the image
; $iH - Height of the image
; Return values .: Dllstruct containing the image informations
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......: _Image_CreateFromFile, _Image_Delete
; Link ..........:
; Example .......:
; ===========================================================================================
Func _Image_Create($iW, $iH)
Local $Ptr, $hDC, $hBmp, $tBMI, $aDIB, $vStruct
$hDC = _WinAPI_CreateCompatibleDC(0)
$tBMI = DllStructCreate('struct;dword Size;long Width;long Height;word Planes;word BitCount;dword Compression;dword SizeImage;long XPelsPerMeter;long YPelsPerMeter;dword ClrUsed;dword ClrImportant;endstruct;dword RGBQuad')
DllStructSetData($tBMI, 'Size', DllStructGetSize($tBMI) - 4)
DllStructSetData($tBMI, 'Width', $iW)
DllStructSetData($tBMI, 'Height', -$iH)
DllStructSetData($tBMI, 'Planes', 1)
DllStructSetData($tBMI, 'BitCount', 32)
$aDIB = DllCall($___ASM_DLL_GDI32, 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hBmp = $aDIB[0]
$Ptr = $aDIB[4]
_WinAPI_SelectObject($hDC, $hBmp)
$vStruct = DllStructCreate('int[5]')
DllStructSetData($vStruct, 1, $hDC, 1)
DllStructSetData($vStruct, 1, $iW, 2)
DllStructSetData($vStruct, 1, $iH, 3)
DllStructSetData($vStruct, 1, $Ptr, 4)
DllStructSetData($vStruct, 1, $hBmp, 5)
Return $vStruct
EndFunc ;==>_Image_Create
; #FUNCTION# ;===============================================================================
; Name...........: _Image_CreateFromFile
; Description ...: Creates an Image from file
; Syntax.........: _Image_CreateFromFile($sPath)
; Parameters ....: $sPath - Path to image file
; Return values .: Dllstruct containing the image informations
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......: _Image_Create, _Image_Delete
; Link ..........:
; Example .......:
; ===========================================================================================
Func _Image_CreateFromFile($sPath)
Local $hImage = _GDIPlus_ImageLoadFromFile($sPath)
Local $iW = _GDIPlus_ImageGetWidth($hImage)
Local $iH = _GDIPlus_ImageGetHeight($hImage)
Local $vImage = _Image_Create($iW, $iH)
Local $hGraphic = _GDIPlus_GraphicsCreateFromHDC(DllStructGetData($vImage, 1, 1))
_GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphic)
Return $vImage
EndFunc ;==>_Image_CreateFromFile
; #FUNCTION# ;===============================================================================
; Name...........: _Image_Delete
; Description ...: Deletes an Image
; Syntax.........: _Image_Delete(ByRef $vStruct)
; Parameters ....: $vStruct - DllStruct returned by an Image_Create function
; Return values .: None
; Author ........: Mars
; Modified.......:
; Remarks .......:
; Related .......: _Image_Create, _Image_CreateFromFile
; Link ..........:
; Example .......:
; ===========================================================================================
Func _Image_Delete(ByRef $vStruct)
_WinAPI_DeleteObject(DllStructGetData($vStruct, 1, 5))
_WinAPI_DeleteDC(DllStructGetData($vStruct, 1, 1))
$vStruct = 0
EndFunc ;==>_Image_Delete
#endregion - Teile der ImageUDF
[/autoit]Um Von GDI(+) auf ASM zu schalten muss in Zeile 8 das $UseASM auf False gesetzt werden.
Es wird jetzt automatisch zwischen ASM und GDI(+) hin und her geschaltet und ein Mittel gebildet.
Leider verspielt FillRect alle rausgeholten ms wieder, sodass ASM und GDI im Beispiel etwa gleich sein sollten.
Bugfix - MoveMemory ließ das Programm beim Beenden abschmieren.