Ich hatte Langeweile und hab kurz etwas zusammengescriptet: es erstellt aus einer Zufallszahl unterschiedliche Bilder bzw. Muster, die teilweise ganz gut aussehen.
Ein paar Beispiele:
[unten]
Und der Code:
Spoiler anzeigen
#include <gdip.au3>
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Local $w=500
Local $h=500
Local $path=FileSaveDialog("Speichern...","D:\Downloads\zzzzztest.png","PNG(*.png)")
Local $gra=_GDIPlus_GraphicsCreateFromHDC(_WinAPI_GetDC(0))
Local $bmp=_GDIPlus_BitmapCreateFromGraphics($w,$h,$gra)
_GDIPlus_GraphicsDispose($gra)
Local $start=Random(0,256)
ConsoleWrite($start&@CRLF)
For $y=0 To $h
For $x=0 To $w
$r=$x*Sin($y*$start)
$g=$x*Cos($y*$start)
$b=$x*Tan($y*$start)
$color="0xFF"&Hex($r,2)&Hex($g,2)&Hex($b,2)
_GDIPlus_BitmapSetPixel($bmp,$x,$y,$color)
Next
Next
FileDelete($path)
_GDIPlus_ImageSaveToFile($bmp,$path)
_GDIPlus_BitmapDispose($bmp)
_GDIPlus_Shutdown()
Beispiele
[Blockierte Grafik: http://img716.imageshack.us/img716/149/zzzzz30.png]
[Blockierte Grafik: http://img20.imageshack.us/img20/4033/zzzzz22.png]
[Blockierte Grafik: http://img37.imageshack.us/img37/2332/zzzzz10.png]
EDIT: versucht mal $start=0.01 und $start=0.005, das sieht wie gezoomt aus
EDIT:
Das ganze ist jetzt in ASM fertig, es ist wirklich viiieeel schneller! (Dank der Hilfe von Andy fertig , sonst würde ich noch dran sitzen)
---Berichtigt und verbessert---
Spoiler anzeigen
#include "AssembleIt.au3"
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
;##########################
Local $von=0.01,$bis=0.01,$step=0.001
;Local $path = "D:\Downloads\zzzzztest.png"
Local $bmp, $lock, $w = 500, $h = 500
Local $fps=0
_GDIPlus_Startup()
Local $gra = _GDIPlus_GraphicsCreateFromHDC(_WinAPI_GetDC(0))
$bmp = _GDIPlus_BitmapCreateFromGraphics($w, $h, $gra)
_GDIPlus_GraphicsDispose($gra)
$hgui=GUICreate("Show",$w,$h)
GUISetState()
$DC_gui=_WinAPI_GetDC($hgui)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DC_gui = ' & $DC_gui & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
global $ptr,$hbmp
$DC_bitmap=_CreateNewBmp32($w, $h, $ptr, $hbmp)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DC_bitmap = ' & $DC_bitmap & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
AdlibRegister("fps",1000)
[/autoit] [autoit][/autoit] [autoit]For $bildwert=$von To $bis Step $step
If GUIGetMsg()=-3 Then _exit()
Local $ret = _AssembleIt("float", "F", "int", $W, "int", $H, "ptr", $ptr, "float", $bildwert)
;ConsoleWrite("Benutzter Wert: " & $ret & @CRLF)
_WinAPI_BitBlt($DC_gui,0,0,$w,$h,$DC_bitmap,0,0,$srccopy)
$fps+=1
Sleep(10)
Next
While GUIGetMsg()<>-3
_WinAPI_BitBlt($DC_gui,0,0,$w,$h,$DC_bitmap,0,0,$srccopy)
Sleep(10)
WEnd
;FileDelete($path)
;_GDIPlus_ImageSaveToFile($bmp, $path)
_exit()
Func _exit()
_DeleteBitmap32($DC_bitmap,$ptr,$hbmp)
_GDIPlus_Shutdown()
Exit
EndFunc
;##########################
Func fps()
ConsoleWrite("FPS: "&$fps&@CRLF)
$fps=0
EndFunc
Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
$hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
$tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
DllStructSetData($tBMI, "Width", $iwidth)
DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
$adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
$ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>_CreateNewBmp32
Func _DeleteBitmap32($DC, $ptr, $hbmp)
_WinAPI_DeleteDC($DC)
_WinAPI_DeleteObject($hbmp)
$ptr = 0
EndFunc ;==>_DeleteBitmap32
Func F()
_("use32")
_("org " & FasmGetBasePtr($Fasm))
_("finit") ;Co Prozessor starten
;
_("mov eax,[esp+4]") ;
_("mov [w],eax") ;w
_("mov eax,[esp+8]") ;
_("mov [h],eax") ;h
;startadresse in ebx, dann muss ebx immer nur um 4 erhöht werden, um das nächste pixel zu schreiben
_("mov ebx,[esp+12]") ;scan0
_("mov eax,[w]") ;an das ende setzen, weil die schleifen auch von hinten anfangen
_("imul eax,[h]") ;w*h
_("imul eax,4") ;je pixel 4 bytes: w*h*4
_("add ebx,eax") ;scan0 += size
_("mov eax,[esp+16]") ;start / bildwert
_("mov [start],eax") ;
;register im coprostack belegen,
[/autoit] [autoit][/autoit] [autoit]_("fld [start]") ;st0=start
_("mov edx,[h]") ;Schleifenzähler edx für y, For $edx=$h to 0 Step -1
_("for_y:") ;Schleifenlabel
_("mov ecx,[w]") ;Schleifenzähler ecx für x
_("for_x:") ;Schleifenlabel
;Berechung
;st0=start
_("mov [ftemp],edx") ;st0=start
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fptan") ;st0=1 st1=tangens !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!, (tan, in ASM umgekehrt, bgra)
_("fstp st0") ;stack sauber machen
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=sin(y*start) st2=start
_("fmulp") ;st0=x*sin(y*start) st1=start
_("fistp dword[r]") ;st0=start ACHTUNG, entweder stack immer komplett leermachen oder einfach die werte weiterbenutzen!!
;ansonsten läuft der stack über...stackoverflow
_("mov [ftemp],edx") ;das ganze mit g und cos
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fcos") ;
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=y*start st2=start
_("fmulp") ;st1=x*(y*start) st1=start
_("fistp dword[g]") ;st0=start
_("mov [ftemp],edx") ;und b und tan
_("fild [ftemp]") ;
_("fmul st0,st1") ;
_("fsin") ;st0=sin(y*start) st1=start
_("mov [ftemp],ecx") ;st0=tangens
_("fild [ftemp]") ;
_("fmulp") ;
_("fistp dword[b]") ;st0=start, stack muss gecleant werden in der schleife!
_("mov byte[code=c],255") ;alpha auf 255 setzen
_("mov eax,dword[r]") ;die 4 aufeinanderfolgenden bytes holen
_("mov DWORD[ebx],eax") ;color in [ebx] (bild) schreiben
_("sub ebx,4") ;ein pixel weiter bzw. zurück
_("dec ecx") ;Zähler dekrementieren
_("jnz for_x") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("dec edx") ;Zähler dekrementieren
_("jnz for_y") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("fstp st0") ;stack sauber machen
_("fld [start]") ;Rückgabewert=Start / Bildwert
_("ret") ;Ende, Rückgabewert ist der letzte Wert des ERSTEN! Pixels (Scheife geht Rückwärts)
_("r db 0") ;
_("g db 0") ;
_("b db 0") ;
_("c dd 0") ;dummy, platz zum schreiben von dword nach [b]
_("ftemp dd 0.0") ;zum schreiben von edx/ecx auf floating stack
_("start dd 0.0") ;für berechnung
_("w dd 0") ;Speicher für Parameter reservieren
_("h dd 0") ;
EndFunc
EDIT:
Das ganze nochmal schneller (es wird in der Schleife nicht mehr assemblet):
Spoiler anzeigen
;#include "AssembleIt.au3"
#include "Fasm.au3"
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
;##########################
Local $von=0.0,$bis=ACos(-1)*2,$step=0.001
;Local $path = "D:\Downloads\zzzzztest.png"
Local $bmp, $lock, $w = 500, $h = 500
Local $fps=0
_GDIPlus_Startup()
Local $gra = _GDIPlus_GraphicsCreateFromHDC(_WinAPI_GetDC(0))
$bmp = _GDIPlus_BitmapCreateFromGraphics($w, $h, $gra)
_GDIPlus_GraphicsDispose($gra)
$hgui=GUICreate("Show",$w,$h)
GUISetState()
$DC_gui=_WinAPI_GetDC($hgui)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DC_gui = ' & $DC_gui & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
global $ptr,$hbmp
$DC_bitmap=_CreateNewBmp32($w, $h, $ptr, $hbmp)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ptr = ' & $ptr & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DC_bitmap = ' & $DC_bitmap & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
Local $Fasm = FasmInit()
FasmReset($Fasm)
F()
$bcode=FasmGetBinary($Fasm)
Local $tCodebuffer=DllStructCreate("byte["&StringLen($bcode)/2-1&"]")
DllStructSetData($tCodeBuffer,1,$bcode)
Local $user32=DllOpen("user32.dll")
AdlibRegister("fps",1000)
[/autoit] [autoit][/autoit] [autoit]For $bildwert=$von To $bis Step $step
If GUIGetMsg()=-3 Then _exit()
;Local $ret = _AssembleIt("float", "F", "int", $W, "int", $H, "ptr", $ptr, "float", $bildwert)
;ConsoleWrite("Benutzter Wert: " & $ret & @CRLF)
Local $ret=DllCall($user32, "float", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "int", $W, "int", $H, "ptr", $ptr, "float", $bildwert)
;ConsoleWrite("Benutzter Wert: " & $ret[0] & @CRLF)
_WinAPI_BitBlt($DC_gui,0,0,$w,$h,$DC_bitmap,0,0,$srccopy)
$fps+=1
Sleep(10)
Next
While GUIGetMsg()<>-3
_WinAPI_BitBlt($DC_gui,0,0,$w,$h,$DC_bitmap,0,0,$srccopy)
Sleep(10)
WEnd
;FileDelete($path)
;_GDIPlus_ImageSaveToFile($bmp, $path)
_exit()
Func _exit()
_DeleteBitmap32($DC_bitmap,$ptr,$hbmp)
_GDIPlus_Shutdown()
DllClose($user32)
Exit
EndFunc
;##########################
Func fps()
ConsoleWrite("FPS: "&$fps&@CRLF)
$fps=0
EndFunc
Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
$hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
$tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
DllStructSetData($tBMI, "Width", $iwidth)
DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
$adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
$ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>_CreateNewBmp32
Func _DeleteBitmap32($DC, $ptr, $hbmp)
_WinAPI_DeleteDC($DC)
_WinAPI_DeleteObject($hbmp)
$ptr = 0
EndFunc ;==>_DeleteBitmap32
Func F()
_("use32")
_("org " & FasmGetBasePtr($Fasm))
_("finit") ;Co Prozessor starten
;
_("mov eax,[esp+4]") ;
_("mov [w],eax") ;w
_("mov eax,[esp+8]") ;
_("mov [h],eax") ;h
;startadresse in ebx, dann muss ebx immer nur um 4 erhöht werden, um das nächste pixel zu schreiben
_("mov ebx,[esp+12]") ;scan0
_("mov eax,[w]") ;an das ende setzen, weil die schleifen auch von hinten anfangen
_("imul eax,[h]") ;w*h
_("imul eax,4") ;je pixel 4 bytes: w*h*4
_("add ebx,eax") ;scan0 += size
_("mov eax,[esp+16]") ;start / bildwert
_("mov [start],eax") ;
;register im coprostack belegen,
[/autoit] [autoit][/autoit] [autoit]_("fld [start]") ;st0=start
_("mov edx,[h]") ;Schleifenzähler edx für y, For $edx=$h to 0 Step -1
_("for_y:") ;Schleifenlabel
_("mov ecx,[w]") ;Schleifenzähler ecx für x
_("for_x:") ;Schleifenlabel
;Berechung
;st0=start
_("mov [ftemp],edx") ;st0=start
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fptan") ;st0=1 st1=tangens !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!, (tan, in ASM umgekehrt, bgra)
_("fstp st0") ;stack sauber machen
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=sin(y*start) st2=start
_("fmulp") ;st0=x*sin(y*start) st1=start
_("fistp dword[r]") ;st0=start ACHTUNG, entweder stack immer komplett leermachen oder einfach die werte weiterbenutzen!!
;ansonsten läuft der stack über...stackoverflow
_("mov [ftemp],edx") ;das ganze mit g und cos
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fcos") ;
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=y*start st2=start
_("fmulp") ;st1=x*(y*start) st1=start
_("fistp dword[g]") ;st0=start
_("mov [ftemp],edx") ;und b und tan
_("fild [ftemp]") ;
_("fmul st0,st1") ;
_("fsin") ;st0=sin(y*start) st1=start
_("mov [ftemp],ecx") ;st0=tangens
_("fild [ftemp]") ;
_("fmulp") ;
_("fistp dword[b]") ;st0=start, stack muss gecleant werden in der schleife!
_("mov byte[code=c],255") ;alpha auf 255 setzen
_("mov eax,dword[r]") ;die 4 aufeinanderfolgenden bytes holen
_("mov DWORD[ebx],eax") ;color in [ebx] (bild) schreiben
_("sub ebx,4") ;ein pixel weiter bzw. zurück
_("dec ecx") ;Zähler dekrementieren
_("jnz for_x") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("dec edx") ;Zähler dekrementieren
_("jnz for_y") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("fstp st0") ;stack sauber machen
_("fld [start]") ;Rückgabewert=Start / Bildwert
_("ret") ;Ende, Rückgabewert ist der letzte Wert des ERSTEN! Pixels (Scheife geht Rückwärts)
_("r db 0") ;
_("g db 0") ;
_("b db 0") ;
_("c dd 0") ;dummy, platz zum schreiben von dword nach [b]
_("ftemp dd 0.0") ;zum schreiben von edx/ecx auf floating stack
_("start dd 0.0") ;für berechnung
_("w dd 0") ;Speicher für Parameter reservieren
_("h dd 0") ;
EndFunc
Func _($str)
FasmAdd($Fasm, $str)
EndFunc
Jetzt 21,5 FPS bei 500x500px