Moin
Es geht darum möglichst Schnell ein Perlin-Noise Bild zu erstellen.
(Was das ist steht auf Wikipedia: http://de.wikipedia.org/wiki/Perlin-Noise)
Folgende Kritierien müssen erfüllt sein.
- Die Funktion liefert (mindestens) ein hDC. (Es darf natürlich auch hbmp, ptr, breite und höhe mitgeliefert werden)
- Die Funktion muss ausschließlich mit AutoIt gecodet sein. Es darf jede Beliebige Standard Windows Dll (von XP ausgehend) genutzt werden. Jede beliebige UDF Darf genutzt werden.
Folgende Eingaben müssen vorhanden sein:
- Breite (Breite des Bildes)
- Höhe (Höhe des Bildes)
- Helligkeit (in einer beliebigen Skala z.B. von 0 bis 255)
- Tiefe (Wie Tief wird die Perlin Berechnung bemacht). Es MUSS Die Bildgröße überprüft werden was die Maximal Mögliche Tiefe ist. Und wenn die Eingegebene über diesem Wert liegt wird sie auf die Maximal Mögliche Größe verringert (z.B. ich gebe Tiefe 10 ein, das Bild ist aber nur 200x200, dann wird die Tiefe automatisch auf 5 oder so verringert)
If $Tiefe < 1 Then $Tiefe = 1
If Int(Log2(_Min($b, $h))) - 1 <= Int($Tiefe) Then $Tiefe = Int(Log2(_Min($b, $h))) - 2 ;Überprüfung ob die Tiefe möglich ist bei der angegebenen Auflösung
- Nummer (Es gibt Theoretisch nahezu unendlich viele Möglichkeiten wie das Endbild aussieht, wenn man jeden Pixel einfach mit Random 0/1 Schwarz oder weiß färbt. Es muss aber möglich sein ein bestimmtes Bild wieder zu erhalten egal wann man die Funktion aufruft. Es bietet sich eine RandomFunktion mit Startwert an die je nach Startwert andere Randomzahlen generiert)
Auswertung:
Bewertet wird die Geschwindigkeit bei der Auflösung von 200x200, 400x400 und 600x600 Pixeln und maximaler Tiefe auf meinem Rechner. (Wenn jeder das bei sich daheim Testet gibts keine einheitlichen Ergebnisse)
Ich habe auch schonmal eine Perlin Funktion testweise geschrieben, die ist aber extrem langsam.
Spoiler anzeigen
#include <Misc.au3>
#include <WinAPIEX.au3>
#include <GDIPlus.au3>
;~ #include <array.au3>
Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Global Const $Size = 200
Global Const $Breite = $Size
Global Const $Hoehe = $Size
Global Const $Titel = 'Mustergenerator...'
Global Const $WS_EX_LAYERED = 0x00080000
Global Const $WS_POPUP = 0x80000000
Global Const $SRCCOPY = 0x00CC0020
Global Const $BLACKNESS = 0x00000042
Global Const $h_NTDLL_DLL = DllOpen('ntdll.dll')
Global Const $h_MSIMG32_DLL = DllOpen('msimg32.dll')
Global Const $gdi32 = DllOpen('gdi32.dll')
Global Const $Stretch = 1
Global Const $WM_NCHITTEST = 0x0084
Global Const $HTCAPTION = 2
Global $hGUI = GUICreate($Titel, $Breite * $Stretch, $Hoehe * $Stretch, _C($Breite * $Stretch, 1), _C($Hoehe * $Stretch, 0), $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0x000000, $hGUI)
WinSetTrans($hGUI, '', 255)
GUISetOnEvent(-3, '_Exit', $hGUI)
GUISetState(@SW_SHOW, $hGUI)
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Global $hDC_GUI = _WinAPI_GetDC($hGUI)
Global $ptr_Backbuffer, $hbmp_Backbuffer
Global $hDC_Backbuffer = _CreateNewBmp32($Breite, $Hoehe, $ptr_Backbuffer, $hbmp_Backbuffer)
Global $DLL_Struct = DllStructCreate('int[' & $Breite * $Hoehe & ']', $ptr_Backbuffer)
Global $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_GUI)
Global $Frame, $Struct, $ptr, $hbmp
Global $Counter = 0
Global $Mode = 1 ;0 = NeuesBild, 1=PerlinNoise, gen1
Global $Neu = True
OnAutoItExitRegister('_Exit')
GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
Local $Timer = TimerInit()
[/autoit] [autoit][/autoit] [autoit]Switch $Mode
Case 0
Local $a = _Generator_Kleeblatt($Breite, $Hoehe)
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
Case 1
Local $a = _Generator_Perlin($Breite, $Hoehe, 15, 0.9, Random(1, 5000))
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
Case 2
Local $a = _Generator_1($Breite, $Hoehe)
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
EndSwitch
[/autoit] [autoit][/autoit] [autoit]ToolTip(TimerDiff($Timer))
;~ _Filter_1($hbmp, $ptr, 2)
;~ _Filter_1($hbmp, $ptr, 4, 1)
While Sleep(20)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $Breite * $Stretch, $Hoehe * $Stretch, $Frame, 0, 0, $Breite, $Hoehe, $SRCCOPY)
If _IsPressed('20') Then _Neu()
If _IsPressed('53') Then _Save()
WEnd
Func _Neu()
Local $Timer = TimerInit()
Switch $Mode
Case 0
_Delete_Bitmap32($Frame, $hbmp)
Local $a = _Generator_Kleeblatt($Breite, $Hoehe)
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
Case 1
_Delete_Bitmap32($Frame, $hbmp)
Local $a = _Generator_Perlin($Breite, $Hoehe, 15, 0.9, Random(1, 5000))
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
Case 2
_Delete_Bitmap32($Frame, $hbmp)
Local $a = _Generator_1($Breite, $Hoehe)
$Frame = $a[0]
$ptr = $a[2]
$hbmp = $a[1]
EndSwitch
ToolTip(TimerDiff($Timer))
;~ _Filter_1($hbmp, $ptr, 2)
;~ _Filter_1($hbmp, $ptr, 2, 1)
EndFunc ;==>_Neu
Func _Generator_Perlin($b, $h, $t = 15, $he = 1, $nr = 1)
Return _PerlinNoise($b, $h, $t, $he, $nr)
EndFunc ;==>_Generator_Perlin
Func _Generator_Kleeblatt($b, $h)
Return _NeuesBild($b, $h, 1)
EndFunc ;==>_Generator_Kleeblatt
Func _Generator_1($b, $h)
Return _NeuesBild($b, $h, 2)
EndFunc ;==>_Generator_1
;~ Richtung:
;~ 0 = Waagerecht
;~ 1 = Senktecht
;~ 2 = Diagonal lu ro
;~ 3 = Diagonal lo Run
;~ abs
;~ jede X-te Linie wird gezogen
;~ tausch
;~ 0 = x = x
;~ 1 = x = y, y = x
Func _Filter_1($hbmp, $ptr, $abs = 2, $richtung = 0, $Farbe = 0xFF000000, $ersetzen = True)
Local $tmpcol[4]
$Farbe = Hex($Farbe,
$tmpcol[0] = Int('0x' &StringLeft($Farbe, 2))
$tmpcol[1] = Int('0x' &StringMid($Farbe, 3, 2))
$tmpcol[2] = Int('0x' &StringMid($Farbe, 5, 2))
$tmpcol[3] = Int('0x' &StringMid($Farbe, 7, 2))
___Filter_1($hbmp, $ptr, $abs, $richtung, $tmpcol[0], $tmpcol[1], $tmpcol[2], $tmpcol[3], $ersetzen)
EndFunc
Func ___Richtung($r, ByRef $x, ByRef $y, $h, $z = 0) ;z bedeutet, dass alles wieder hergestellt wird. Bei einem einfachen Tausch ist das ohne speichern möglich.
Local $t, $Counter = 0
Local Static $x2, $y2
Switch $r
Case 1
$t = $x
$x = $y
$y = $t
Case 2
Switch $Z
Case 0
$x2 = $x ;Speichern von x und y zum späteren korrekten wiederherstellen
$y2 = $y
$x = $x + ($y - 1)
While $x > $h
$x -= $h
$Counter += 1
WEnd
If $x < $y-1 Then
$x -= $Counter
EndIf
While $x < 0
$x += ($h + 1)
WEnd
Case 1
$x = $x2
$y = $y2
EndSwitch
Case 3
Switch $Z
Case 0
$x2 = $x ;Speichern von x und y zum späteren korrekten wiederherstellen
$y2 = $y
$x = $x - $y
While $x < 0
$x += $h
WEnd
;~ $x -= 1
Case 1
$x = $x2
$y = $y2
EndSwitch
EndSwitch
EndFunc
Func ___Filter_1($hbmp, $ptr, $abs, $richtung, $a, $r, $g, $blau, $ersetzen)
Local $bit = _GDIPlus_BitmapCreateFromHBITMAP($hbmp)
Local $b = _GDIPlus_ImageGetWidth($bit)
Local $h = _GDIPlus_ImageGetHeight($bit)
_GDIPlus_BitmapDispose($bit)
Local $Struct = DllStructCreate('int[' & $b * $h & ']', $ptr)
Local $tmpcol[4] ;argb
Local $tmp2, $tmp3 ;tmp2 = komplett argb, tmp3 = Multi für den Aplhawert
_Winapi_StretchBlt($hDC_Backbuffer, 0, 0, $b * $Stretch, $h * $Stretch, $Frame, 0, 0, $b, $h, $SRCCOPY)
Local $hBuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_Backbuffer)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF)
Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
Local $Prozent = 0
Local $pxGes = $h * $b
Switch $richtung
Case 0
For $x = 0 To $h Step 1
For $y = 0 To $b Step 1
If $x / $abs = Int($x / $abs) And $y <> $b Then
___Richtung($richtung, $x, $y, $h)
[/autoit] [autoit][/autoit] [autoit]Switch $ersetzen
Case True
DllStructSetData($Struct, 1, '0x' & Hex($a,2) & Hex($r,2) & Hex($g,2) & Hex($blau,2), $x * $b + $y + 1)
Case False
$tmp2 = Hex(DllStructGetData($Struct, 1, $x * $b + $y + 1),
$tmpcol[0] = Int('0x' &StringLeft($tmp2, 2))
$tmpcol[1] = Int('0x' &StringMid($tmp2, 3, 2))
$tmpcol[2] = Int('0x' &StringMid($tmp2, 5, 2))
$tmpcol[3] = Int('0x' &StringMid($tmp2, 7, 2))
$tmp3 = $a / 255
$tmpcol[1] = $tmpcol[1] + $r * $tmp3
$tmpcol[2] = $tmpcol[2] + $g * $tmp3
$tmpcol[3] = $tmpcol[3] + $blau * $tmp3
For $i = 1 To 3 Step 1
If $tmpcol[$i] > 255 Then $tmpcol[$i] = 255
Next
If ($x * $b + $y)< $h*$b Then
DllStructSetData($Struct, 1, '0x' & Hex($tmpcol[0], 2) & Hex($tmpcol[1], 2) & Hex($tmpcol[2], 2) & Hex($tmpcol[3], 2), $x * $b + $y + 1)
EndIf
EndSwitch
___Richtung($richtung, $x, $y, $h, 1)
[/autoit] [autoit][/autoit] [autoit]EndIf
[/autoit] [autoit][/autoit] [autoit]Next
$Prozent = ($x * $y + $b) / $pxGes
_GDIPlus_GraphicsDrawRect($hBuffer, 5, $h - 20, $b - 10, 15, $hPen)
_GDIPlus_GraphicsFillRect($hBuffer, 7, $h - 18, ($b - 13) * $Prozent, 12, $hBrush)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $b * $Stretch, $h * $Stretch, $hDC_Backbuffer, 0, 0, $b, $h, $SRCCOPY)
Next
Case 1
For $x = 0 To $b Step 1
For $y = 0 To $h Step 1
If $x / $abs = Int($x / $abs) And $y <> $b Then
___Richtung($richtung, $x, $y, $h)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Switch $ersetzen
Case True
DllStructSetData($Struct, 1, '0x' & Hex($a,2) & Hex($r,2) & Hex($g,2) & Hex($blau,2), $x * $b + $y + 1)
Case False
$tmp2 = Hex(DllStructGetData($Struct, 1, $x * $b + $y + 1),
$tmpcol[0] = Int('0x' &StringLeft($tmp2, 2))
$tmpcol[1] = Int('0x' &StringMid($tmp2, 3, 2))
$tmpcol[2] = Int('0x' &StringMid($tmp2, 5, 2))
$tmpcol[3] = Int('0x' &StringMid($tmp2, 7, 2))
$tmp3 = $a / 255
$tmpcol[1] = $tmpcol[1] + $r * $tmp3
$tmpcol[2] = $tmpcol[2] + $g * $tmp3
$tmpcol[3] = $tmpcol[3] + $blau * $tmp3
For $i = 1 To 3 Step 1
If $tmpcol[$i] > 255 Then $tmpcol[$i] = 255
Next
If ($x * $b + $y)< $h*$b Then
DllStructSetData($Struct, 1, '0x' & Hex($tmpcol[0], 2) & Hex($tmpcol[1], 2) & Hex($tmpcol[2], 2) & Hex($tmpcol[3], 2), $x * $b + $y + 1)
EndIf
EndSwitch
___Richtung($richtung, $x, $y, $h, 1)
[/autoit] [autoit][/autoit] [autoit]EndIf
[/autoit] [autoit][/autoit] [autoit]Next
$Prozent = ($x * $y + $b) / $pxGes
_GDIPlus_GraphicsDrawRect($hBuffer, 5, $h - 20, $b - 10, 15, $hPen)
_GDIPlus_GraphicsFillRect($hBuffer, 7, $h - 18, ($b - 13) * $Prozent, 12, $hBrush)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $b * $Stretch, $h * $Stretch, $hDC_Backbuffer, 0, 0, $b, $h, $SRCCOPY)
Next
Case 2 To 3
[/autoit] [autoit][/autoit] [autoit]For $x = 0 To $h Step 1
For $y = 0 To $b Step 1
If $x / $abs = Int($x / $abs) And $y <> $b Then
___Richtung($richtung, $x, $y, $h)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Switch $ersetzen
Case True
DllStructSetData($Struct, 1, '0x' & Hex($a,2) & Hex($r,2) & Hex($g,2) & Hex($blau,2), $x * $b + $y + 1)
Case False
$tmp2 = Hex(DllStructGetData($Struct, 1, $x * $b + $y + 1),
$tmpcol[0] = Int('0x' &StringLeft($tmp2, 2))
$tmpcol[1] = Int('0x' &StringMid($tmp2, 3, 2))
$tmpcol[2] = Int('0x' &StringMid($tmp2, 5, 2))
$tmpcol[3] = Int('0x' &StringMid($tmp2, 7, 2))
$tmp3 = $a / 255
$tmpcol[1] = $tmpcol[1] + $r * $tmp3
$tmpcol[2] = $tmpcol[2] + $g * $tmp3
$tmpcol[3] = $tmpcol[3] + $blau * $tmp3
For $i = 1 To 3 Step 1
If $tmpcol[$i] > 255 Then $tmpcol[$i] = 255
Next
If ($x * $b + $y)< $h*$b Then
DllStructSetData($Struct, 1, '0x' & Hex($tmpcol[0], 2) & Hex($tmpcol[1], 2) & Hex($tmpcol[2], 2) & Hex($tmpcol[3], 2), $x * $b + $y + 1)
EndIf
EndSwitch
___Richtung($richtung, $x, $y, $h, 1)
[/autoit] [autoit][/autoit] [autoit]EndIf
[/autoit] [autoit][/autoit] [autoit]Next
$Prozent = ($x * $y + $b) / $pxGes
_GDIPlus_GraphicsDrawRect($hBuffer, 5, $h - 20, $b - 10, 15, $hPen)
_GDIPlus_GraphicsFillRect($hBuffer, 7, $h - 18, ($b - 13) * $Prozent, 12, $hBrush)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $b * $Stretch, $h * $Stretch, $hDC_Backbuffer, 0, 0, $b, $h, $SRCCOPY)
Next
EndSwitch
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
$Struct = 0
EndFunc ;==>_Filter_1
;##########################HIER EIGENE FORMELN EINBAUEN############################################
; r = Rotanteil
; g = Grünanteil
; b = Blauanteil
; Es muss das Hex-Format verwendet werden. Hex(blabla, 2)
Func _Funktion($x, $y, ByRef $r1, ByRef $g1, ByRef $b1, ByRef $a1)
Local $col, $r, $g, $b, $AbstandMitte, $atx, $aty, $atx2, $aty2
[/autoit] [autoit][/autoit] [autoit]Local Static $Counter = 0
$Counter += 1
If $Neu Then
$Neu = False
$Counter = 0
EndIf
$AbstandMitte = (($y - $Hoehe / 2) ^ 2 + ($Breite / 2 - $x) ^ 2) ^ 0.5
$atx = ATan2($x, $AbstandMitte)
$aty = ATan2($y, $AbstandMitte)
$atx2 = ATan2($Breite - $x, $AbstandMitte)
$aty2 = ATan2($Hoehe - $y, $AbstandMitte)
;~ $r = Hex($AbstandMitte + Random(0, 4, 1) ,2)
;~ $g = Hex(Sin($AbstandMitte/50) * 200 + Random(0, 4, 1) , 2)
;~ $b = Hex(Cos($AbstandMitte/20)*200 , 2)
$r = Hex(Tan($atx * 5 + 2) * 62, 2) + Hex(Tan($atx2 * 5 + 2) * 62, 2) + Hex(Tan($aty * 5 + 2) * 62, 2) + Hex(Tan($aty2 * 5 + 2) * 62, 2)
$g = Hex(Tan($atx * 5 - 2) * 62, 2) + Hex(Tan($atx2 * 5 - 2) * 62, 2) + Hex(Tan($aty * 5 - 2) * 62, 2) + Hex(Tan($aty2 * 5 - 2) * 62, 2)
$b = Hex(Tan($atx * 5) * 62, 2) + Hex(Tan($atx2 * 5) * 62, 2) + Hex(Tan($aty * 5) * 62, 2) + Hex(Tan($aty2 * 5) * 62, 2)
;~ $r += Hex(Tan($atx2*5 + 2)*70, 2)
;~ $g += Hex(Tan($atx2*5 - 2)*70, 2)
;~ $b += Hex(Tan($atx2*5)*70, 2)
;~ $r += Hex(Tan($aty*5 + 2)*70, 2)
;~ $g += Hex(Tan($aty*5 - 2)*70, 2)
;~ $b += Hex(Tan($aty*5)*70, 2)
;~ $r += Hex(Tan($aty2*5 + 2)*70, 2)
;~ $g += Hex(Tan($aty2*5 - 2)*70, 2)
;~ $b += Hex(Tan($aty2*5)*70, 2)
If $col Then Return $col
[/autoit] [autoit][/autoit] [autoit]$r1 = Hex($r, 2)
$g1 = Hex($g, 2)
$b1 = Hex($b, 2)
$a1 = 'FF'
Return 0
EndFunc ;==>_Funktion
;###################################################################################################
Func _Gen1($x, $y)
Local $col, $r, $g, $b, $AbstandMitte, $atx, $aty, $atx2, $aty2
$AbstandMitte = (($y - $Hoehe / 2) ^ 2 + ($Breite / 2 - $x) ^ 2) ^ 0.5
$atx = ATan2($x, $AbstandMitte)
$aty = ATan2($y, $AbstandMitte)
$atx2 = ATan2($Breite - $x, $AbstandMitte)
$aty2 = ATan2($Hoehe - $y, $AbstandMitte)
$r = Hex(Tan($atx * 5 + 2) * 62, 2) + Hex(Tan($atx2 * 5 + 2) * 62, 2) + Hex(Tan($aty * 5 + 2) * 62, 2) + Hex(Tan($aty2 * 5 + 2) * 62, 2)
$g = Hex(Tan($atx * 5 - 2) * 62, 2) + Hex(Tan($atx2 * 5 - 2) * 62, 2) + Hex(Tan($aty * 5 - 2) * 62, 2) + Hex(Tan($aty2 * 5 - 2) * 62, 2)
$b = Hex(Tan($atx * 5) * 62, 2) + Hex(Tan($atx2 * 5) * 62, 2) + Hex(Tan($aty * 5) * 62, 2) + Hex(Tan($aty2 * 5) * 62, 2)
Return '0xFF' & Hex($r, 2) & Hex($g, 2) & Hex($b, 2)
EndFunc ;==>_Gen1
Func _F($x)
Return ($x ^ 2 + 5) ^ 0.5
EndFunc ;==>_F
Func _Kleeblatt($x, $y)
Local $w = $Breite, $h = $Hoehe, $r, $g, $b, $p, $col, $l
$r = Sqrt((($w / 2) - $x) ^ 2 + (($h / 2) - $y) ^ 2) / 150
$p = atan2(($w / 2) - $x, ($h / 2) - $y)
$l = $r / (((1 + Cos(4 * $p)) ^ 0.125) - (1 / 40 * (1 + Cos(8 * $p)) ^ 2))
$col = Int(1 / 4 * (1 - $l) ^ 0.125 * (1 + $l ^ 16) * (1 + 3 * $r) * 256) * 256
Return $col
EndFunc ;==>_Kleeblatt
Func ATan2($y, $x)
return (2 * ATan($y / ($x + Sqrt($x * $x + $y * $y))))
EndFunc ;==>ATan2
Func _Min($a, $b)
If $a > $b Then Return $b
Return $a
EndFunc ;==>_Min
Func Log2($x)
Return Log($x) / Log(2) ;10 is the base
EndFunc ;==>Log2
Func _Bet($a)
If $a > 0 Then Return $a
Return -$a
EndFunc ;==>_Bet
Func _Zufall(ByRef $Zufallszahl)
Local Const $a = 7141
Local Const $b = 54773
Local Const $c = 259200
$Zufallszahl = Mod(($a * $Zufallszahl + $b), $c)
If $Zufallszahl < $c / 2 Then
Return 1
Else
Return 0
EndIf
EndFunc ;==>_Zufall
Func _PerlinNoise($b, $h, $Tiefe, $Helligkeit, $Nummer)
If $Tiefe < 1 Then $Tiefe = 1
If Int(Log2(_Min($b, $h))) - 1 <= Int($Tiefe) Then $Tiefe = Int(Log2(_Min($b, $h))) - 2 ;Überprüfung ob die Tiefe möglich ist bei der angegebenen Auflösung
_Winapi_StretchBlt($hDC_Backbuffer, 0, 0, $Breite * $Stretch, $Hoehe * $Stretch, $Frame, 0, 0, $Breite, $Hoehe, $SRCCOPY)
Local $bmp = _GDIPlus_BitmapCreateFromGraphics($b, $h, $hGraphics)
Local $hBu = _GDIPlus_ImageGetGraphicsContext($bmp)
Local $pxGes = 0, $col, $Prozent, $px = 0
For $p = 0 To $Tiefe Step 1 ;p = BildNummern
For $x = 0 To $b / 2 ^ ($Tiefe - $p) Step 1
For $y = 0 To $h / 2 ^ ($Tiefe - $p) Step 1
$pxGes += 1
Next
Next
Next
Local $bmp2 = _GDIPlus_BitmapCloneArea($bmp, 0, 0, $b, $h)
Local $bbuffer = _GDIPlus_ImageGetGraphicsContext($bmp2)
Local $hBuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_Backbuffer)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF)
Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
Local $Erhellen = 1, $Verdunkeln = 1
$Helligkeit = _Bet($Helligkeit)
While $Helligkeit > 2
$Helligkeit -= 1
WEnd
If $Helligkeit < 1 Then
$Verdunkeln = $Helligkeit
$Erhellen = 1
;~ ToolTip('Dunkel: ' & $Verdunkeln)
Else
$Erhellen = 1 - ($Helligkeit - 1)
$Verdunkeln = 1
;~ ToolTip('Hell: ' & $Erhellen)
EndIf
For $p = 0 To $Tiefe Step 1 ;p = BildNummern
For $x = 0 To $b / 2 ^ ($Tiefe - $p) Step 1
For $y = 0 To $h / 2 ^ ($Tiefe - $p) Step 1
$px += 1
Switch _Zufall($Nummer)
Case 0
$col = '0x' & Hex((255 / 2 ^ $p) * $Erhellen, 2) & '000000'
Case 1
$col = '0x' & Hex((255 / 2 ^ $p) * $Verdunkeln, 2) & 'FFFFFF'
EndSwitch
_pix($bmp, $x, $y, $col)
Next
$Prozent = $px / $pxGes
_GDIPlus_GraphicsDrawRect($hBuffer, 5, $Hoehe - 20, $Breite - 10, 15, $hPen)
_GDIPlus_GraphicsFillRect($hBuffer, 7, $Hoehe - 18, ($Breite - 13) * $Prozent, 12, $hBrush)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $Breite * $Stretch, $Hoehe * $Stretch, $hDC_Backbuffer, 0, 0, $Breite, $Hoehe, $SRCCOPY)
Next
_GDIPlus_GraphicsDrawImageRectRect($bbuffer, $bmp, 0, 0, $b / 2 ^ ($Tiefe - $p), $h / 2 ^ ($Tiefe - $p), 0, 0, $b, $h)
Next
Global $_ptr, $_hbmp
Global $_hdc = _CreateNewBmp32($b, $h, $_ptr, $_hbmp)
Local $gra = _GDIPlus_GraphicsCreateFromHDC($_hdc)
_GDIPlus_GraphicsDrawImage($gra, $bmp2, 0, 0)
_GDIPlus_GraphicsDispose($gra)
_GDIPlus_GraphicsDispose($hBu)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_GraphicsDispose($bbuffer)
_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BitmapDispose($bmp)
_GDIPlus_BitmapDispose($bmp2)
Local $a[3] = [$_hdc, $_hbmp, $_ptr]
Return $a
EndFunc ;==>_PerlinNoise
Func _pix($hBitmap, $ix, $iy, $color)
DllCall($ghGDIPDll, "int", "GdipBitmapSetPixel", "hwnd", $hBitmap, "int", $ix, "int", $iy, "dword", $color)
EndFunc ;==>_pix
Func _NeuesBild($b, $h, $func = 0)
[/autoit] [autoit][/autoit] [autoit];~ _GDIPlus_Startup()
_Winapi_StretchBlt($hDC_Backbuffer, 0, 0, $b * $Stretch, $h * $Stretch, $Frame, 0, 0, $b, $h, $SRCCOPY)
Local $hBuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_Backbuffer)
Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF)
Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
Local $g = '00', $r = '00', $bl = '00', $alpha = 'FF'
Local $Prozent = 0
Local $pxGes = $h * $b, $col, $ptr, $hbmp
Local $Frame = _CreateNewBmp32($b, $h, $ptr, $hbmp)
Local $Struct = DllStructCreate('int[' & $b * $h & ']', $ptr)
;~ _Apfelm($Struct)
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To $h Step 1
For $j = 0 To $b Step 1
Switch $func
Case 0
$col = _Funktion($i, $j, $r, $g, $bl, $alpha)
Case 1
$col = _Kleeblatt($j, $i)
Case 2
$col = _Gen1($j, $i)
EndSwitch
If $col Then
DllStructSetData($Struct, 1, $col, $j * $b + $i + 1)
Else
DllStructSetData($Struct, 1, '0x' & $alpha & $r & $g & $bl, $j * $b + $i + 1)
EndIf
Next
$Prozent = ($i * $h + $j) / $pxGes
_GDIPlus_GraphicsDrawRect($hBuffer, 5, $h - 20, $b - 10, 15, $hPen)
_GDIPlus_GraphicsFillRect($hBuffer, 7, $h - 18, ($b - 13) * $Prozent, 12, $hBrush)
_Winapi_StretchBlt($hDC_GUI, 0, 0, $b * $Stretch, $h * $Stretch, $hDC_Backbuffer, 0, 0, $b, $h, $SRCCOPY)
Next
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_PenDispose($hPen)
_GDIPlus_BrushDispose($hBrush)
;~ _GDIPlus_Shutdown()
$Neu = True
Sleep(100)
Local $ret[3] = [$Frame, $hbmp, $ptr]
Return $ret
EndFunc ;==>_NeuesBild
[/autoit] [autoit][/autoit] [autoit]Func _Save()
Local $Pfad = FileSaveDialog('BildSpeichern', @ScriptDir & '\Muster', '(*,.png)', Default, Hex(Random(256, 16 ^ 3, 1), 3) & '.png')
_GDIPlus_Startup()
Local $bm = _GDIPlus_BitmapCreateFromHBITMAP($hbmp)
_GDIPlus_ImageSaveToFile($bm, $Pfad)
_GDIPlus_BitmapDispose($bm)
_GDIPlus_Shutdown()
EndFunc ;==>_Save
Func _Exit()
ConsoleWrite('Blubb')
_WinAPI_ReleaseDC($hGUI, $hDC_GUI)
_GDIPlus_Shutdown()
_Delete_Bitmap32($hDC_Backbuffer, $hbmp_Backbuffer)
_Delete_Bitmap32($Frame, $hbmp)
DllClose($h_NTDLL_DLL)
DllClose($h_MSIMG32_DLL)
DllClose($gdi32)
Exit
EndFunc ;==>_Exit
Func _Delete_Bitmap32($hDC, $hbmp)
_WinAPI_DeleteObject($hbmp)
_WinAPI_ReleaseDC(0, $hDC)
EndFunc ;==>_Delete_Bitmap32
Func _CreateNewBmp32($iWidth, $iHeight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe DC und ptr und handle auf die Bitmapdaten
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $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
Local $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, '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
;_arraydisplay($adib)
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>_CreateNewBmp32
Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
If ($hWnd = $hGUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc ;==>WM_NCHITTEST
Func _C($a, $b)
Switch $b
Case 0 ;Y
Return @DesktopHeight / 2 - $a / 2
Case 1 ;X
Return @DesktopWidth / 2 - $a / 2
EndSwitch
EndFunc ;==>_C
Da ist seeehr viel drin was keiner Braucht.
Nur die Perlinfunktion ist eingestellt.
Also einfach mal Starten. Dann wird bei der Berechnung die verwendete Tiefe angezeigt und danach die benötigte Zeit
Benötigte Zeit:
200x200 Tiefe 5 - 02.851ms --> ca. 14.0 px pro ms
400x400 Tiefe 6 - 11.213ms --> ca. 14.3 px pro ms
600x600 Tiefe 7 - 25.925ms --> ca. 13.8 px pro ms
(Nur so als Referenzwert für eine vergleichsweise langsame Funktion.)
Update
Inzwischen gibt es einen wesentlich schnellere Formel für die Herstellung.
#include <GDIPlus.au3>
[/autoit] [autoit][/autoit] [autoit]Opt('GUICloseOnESC', 0)
Opt('GUIOnEventMode', 0)
;~ Opt('MustDeclareVars', 1)
_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit];################## Hier Parameter bestimmen ###########################
Global $hell = 120 ;Helligkeit des Bildes
Global $Tiefe__ = 15 ;Tiefenwert
Global $Seed = 9 ;Nummer des Bildes
Global $F1 = 0xFF4040A0 ;Farbe 1
Global $F2 = 0xFFFFFFFF ;Farbe 2
Global $Size = 250 ; Welche Breite und Höhe soll das Bild haben ?
Global $Stretch = 2 ;Um welchen Faktor wird das Bild vergrößert ?
;#######################################################################
;~ Global Const $Size = 200
;~ Global Const $Stretch = 2
Global Const $Breite = $Size
Global Const $Hoehe = $Size
Global Const $Titel = 'Perlin'
Global Const $WM_NCHITTEST = 0x0084 ; Fenster "Anfassen"
Global Const $HTCAPTION = 2 ; Fenster "Anfassen"
Global Const $WS_EX_LAYERED = 0x00080000
Global Const $WS_POPUP = 0x80000000
Global Const $SRCCOPY = 0x00CC0020
Global Const $BLACKNESS = 0x00000042
Global Const $DIB_RGB_COLORS = 0 ;Eine Absolut sinnlose Variable die aber immer fehlt.
Global Const $h_NTDLL_DLL = DllOpen('ntdll.dll')
Global Const $h_MSIMG32_DLL = DllOpen('msimg32.dll')
Global Const $h_GDI32_DLL = DllOpen('gdi32.dll')
Global Const $h_OLE32_DLL = DllOpen('ole32.dll')
Global Const $h_USER32_DLL = DllOpen('user32.dll')
Global Const $h_KERNEL32_DLL = DllOpen('kernel32.dll')
Global Const $h_AlphaStruct = _GDI_AlphaBlend_GetStruct()
[/autoit] [autoit][/autoit] [autoit]Global $hGUI = GUICreate($Titel, $Breite * $Stretch, $Hoehe * $Stretch, _C($Breite * $Stretch, 1), _C($Hoehe * $Stretch, 0), $WS_POPUP, $WS_EX_LAYERED)
GUISetBkColor(0xFF0000, $hGUI)
WinSetTrans($hGUI, '', 255)
GUISetOnEvent(-3, '_Exit', $hGUI)
GUISetState(@SW_SHOW, $hGUI)
Global Const $hdc_GUI = _WinAPI_GetDC($hGUI)
[/autoit] [autoit][/autoit] [autoit]Global $Backbuffer = _CreateImage($Breite*$Stretch, $Hoehe*$Stretch)
Global $hDC_Backbuffer = DllStructGetData($Backbuffer, 1, 1)
;~ ;################## Hier Parameter bestimmen ###########################
;~ Global $hell = 120 ;Helligkeit des Bildes
;~ Global $Tiefe__ = 15 ;Tiefenwert
;~ Global $Seed = 9 ;Nummer des Bildes
;~ Global $F1 = 0xFF4040A0 ;Farbe 1
;~ Global $F2 = 0xFFFFFFFF ;Farbe 2
;~ ;#######################################################################
Global $Tiefe_ = 0
Global $Timer = TimerInit()
Global $Perlin = _CreatePerlin($Breite, $Hoehe, $Tiefe__, $Seed, $hell, $F1, $F2)
Global $Diff = Int(TimerDiff($Timer))
Global $ImageSchrift_Zeit = _CreateImageSchrift('Size: ' & $Breite & 'x' & $Hoehe & ' px' & '|Helligkeit: ' & $hell & '|Tiefe: ' & $Tiefe_ & '|Benötigte Zeit: ' & $Diff & ' ms|Pixel pro ms: ' & Round($Breite*$Hoehe/$Diff, 2), 0xFF000000, 4) ; 4px große Schrift
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
OnAutoItExitRegister('_Exit')
While Sleep(100)
$Seed = Random(0, 50000)
_DrawImageStretch($hDC_Backbuffer, 0, 0, $Perlin, $Stretch)
_DrawImageTrans($hDC_Backbuffer, 2*$Stretch, ($Hoehe - DllStructGetData($ImageSchrift_Zeit, 1, 3) - 1)*$Stretch, $ImageSchrift_Zeit, $Stretch)
_DrawImage($hdc_GUI, 0, 0, $Backbuffer)
_DeleteImage($Perlin)
_DeleteImage($ImageSchrift_Zeit)
$hell += 1
If $hell > 255 Then $hell = 0
$Timer = TimerInit()
$Perlin = _CreatePerlin($Breite, $Hoehe, $Tiefe__, $Seed, $hell, $F1, $F2)
$Diff = Int(TimerDiff($Timer))
$ImageSchrift_Zeit = _CreateImageSchrift('Size: ' & $Breite & 'x' & $Hoehe & ' px' & '|Helligkeit: ' & $hell & '|Tiefe: ' & $Tiefe_ & '|Benötigte Zeit: ' & $Diff & ' ms|Pixel pro ms: ' & Round($Breite*$Hoehe/$Diff, 2), 0xFF000000, 4) ; 4px große Schrift
WEnd
Func _Zufall(ByRef $Z) ; Eine Pseudo Zufallszahl wird generiert.
$Z = Mod((7141 * $Z + 54773), 259200)
If $Z < 129600 Then Return 1 ; Nur mit 0 und 1
Return 0
EndFunc ;==>_Zufall
Func _Zufall2(ByRef $Z) ; Eine Pseudo Zufallszahl wird generiert.
$Z = Mod((7141 * $Z + 54773), 259200)
Return $Z / 259200 ; Ein Kommawert zw 0 und 1
EndFunc ;==>_Zufall
Func _CreatePerlin($b, $h, $Tiefe = 15, $Nummer = 1, $Helligkeit = 100, $Farbe1 = 0xFF000000, $Farbe2 = 0xFFFFFFFF)
If $Tiefe < 1 Then $Tiefe = 1
If Int(_Log(_Min($b, $h),2)) - 1 <= Int($Tiefe) Then $Tiefe = Int(_Log(_Min($b, $h),2)) - 1 ;Überprüfung ob die Tiefe möglich ist bei der angegebenen Auflösung
$Tiefe_ = $Tiefe
Local $randx = Int($b/3) ; Ein Rand muss sein, da sonst unten und rechts alles dunkel ist
Local $randy = Int($h/3) ; Und oben und links alles hell. Kommt durch das Vergrößern...
$b += $randx
$h += $randy
Local $img = _CreateImage($b, $h) ;Bild erzeugen Hier liegen die ganzen Verpixelungen
Local $hdc = DllStructGetData($img, 1, 1)
Local $ptr = DllStructGetData($img, 1, 4)
Local $hbmp = DllStructGetData($img, 1, 5)
Local $struct = DllStructCreate('int['& $b * $h &']', $ptr)
Local $ziel = _CreateImage($b, $h) ;Hier wird das Endergebnis zusammengebaut.
Local $hdc_ziel = DllStructGetData($ziel, 1, 1)
Local $tmpImg = _CreateImage($b, $h) ;Hier wird immer jeweils eine Ebene vergrößert.
Local $Mode = 0
$gr = _GDIPlus_GraphicsCreateFromHDC(DllStructGetData($tmpImg, 1, 1))
_GDIPlus_GraphicsSetInterpolationMode($gr, 7)
For $p = 0 To $Tiefe Step 1
For $i = 0 To $b / 2 ^ ($Tiefe - $p) - 1 Step 1
For $o = 0 To $h / 2 ^ ($Tiefe - $p) - 1 Step 1
Switch _Zufall($Nummer)
Case 1
DllStructSetData($struct, 1, $Farbe2, $b * $i + $o + 1)
Case 0
DllStructSetData($struct, 1, $Farbe1, $b * $i + $o + 1)
EndSwitch
Next
Next
$Mode = 1
$bm = _GDIPlus_BitmapCreateFromHBITMAP($hbmp)
_GDIPlus_GraphicsDrawImageRectRect($gr, $bm, 0, 0, $b / 2 ^ ($Tiefe - $p), $h / 2 ^ ($Tiefe - $p), 0, 0, $b, $h)
_GDIPlus_BitmapDispose($bm)
_GDI_AlphaBlend($hdc_ziel, 0, 0, $b, $h, DllStructGetData($tmpImg, 1, 1), 0, 0, $b, $h, _GDI_AlphaBlend_GetStruct(255 / 2 ^ $p))
Next
$b -= $randx
$h -= $randy
Local $tmpImg2 = _CreateImage($b, $h) ; Dieses Bild enthält das Endbild.
_WinAPI_BitBlt(DllStructGetData($tmpImg2, 1, 1), 0, 0, $b, $h, $hdc_ziel, $randx/2,$randy/2, $SRCCOPY) ;Es wird der Mittelteil ins Endbild kopiert. Ränder werden so beschnitten.
Switch $Helligkeit
Case 0 To 255/2
_GDIPlus_GraphicsClear($gr, 0xFF000000) ; TmpImg1 wird nicht mehr gebraucht
_GDI_AlphaBlend(DllStructGetData($tmpImg2, 1, 1), 0, 0, $b, $h, DllStructGetData($tmpImg, 1, 1), 0, 0, 10,10, _GDI_AlphaBlend_GetStruct(255-$Helligkeit*2))
Case 255/2 To 255
_GDIPlus_GraphicsClear($gr, 0xFFFFFFFF) ; TmpImg1 wird nicht mehr gebraucht
_GDI_AlphaBlend(DllStructGetData($tmpImg2, 1, 1), 0, 0, $b, $h, DllStructGetData($tmpImg, 1, 1), 0, 0, 10,10, _GDI_AlphaBlend_GetStruct($Helligkeit*2 - 255))
EndSwitch
_GDIPlus_GraphicsDispose($gr)
_DeleteImage($img)
_DeleteImage($tmpImg)
_DeleteImage($ziel)
Return $tmpImg2
EndFunc ;==>_PerlinNoise
Func _GDIPlus_GraphicsSetInterpolationMode($hGraphics, $iInterpolationMode)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGraphics, "int", $iInterpolationMode)
If @error Then Return SetError(@error, @extended, False)
$GDIP_STATUS = $aResult[0]
Return $aResult[0] = 0
EndFunc ;==>_GDIPlus_GraphicsSetInterpolationMode
Func _WinAPI_SetStretchBltMode($hDC, $iMode)
[/autoit] [autoit][/autoit] [autoit]Local $Ret = DllCall($h_GDI32_DLL, 'int', 'SetStretchBltMode', 'hwnd', $hDC, 'int', $iMode)
[/autoit] [autoit][/autoit] [autoit]If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return 1
EndFunc ;==>_WinAPI_SetStretchBltMode
#cs - Alte Perlin Noise Func
[/autoit] [autoit][/autoit] [autoit]Func _PerlinNoise($b, $h, $Tiefe, $Helligkeit, $Nummer, $hGraphics, $hDC_Backbuffer)
If $Tiefe < 1 Then $Tiefe = 1
If Int(_Log(_Min($b, $h),2)) - 1 <= Int($Tiefe) Then $Tiefe = Int(_Log(_Min($b, $h),2)) - 1 ;Überprüfung ob die Tiefe möglich ist bei der angegebenen Auflösung
$Tiefe_ = $Tiefe
;~ $b = Breite
;~ $h = Hoehe
;~ $Tiefe = Anzahl Bilder
;~ $Helligkeit = 0 - 255
Local $img = _CreateImage($b, $h) ;Bild erzeugen
Local $hdc = DllStructGetData($img, 1, 1)
Local $ptr = DllStructGetData($img, 1, 4)
Local $struct = DllStructCreate('int['&$b * $h&']', $ptr)
Local $bmp = _GDIPlus_BitmapCreateFromGraphics($b, $h, $hGraphics)
Local $hBu = _GDIPlus_ImageGetGraphicsContext($bmp)
Local $col
Local $bmp2 = _GDIPlus_BitmapCloneArea($bmp, 0, 0, $b, $h)
Local $bbuffer = _GDIPlus_ImageGetGraphicsContext($bmp2)
Local $hBuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_Backbuffer)
Local $Erhellen = 1, $Verdunkeln = 1
$Helligkeit = _Betrag($Helligkeit)
While $Helligkeit > 2
$Helligkeit -= 1
WEnd
If $Helligkeit < 1 Then
$Verdunkeln = $Helligkeit
$Erhellen = 1
Else
$Erhellen = 1 - ($Helligkeit - 1)
$Verdunkeln = 1
EndIf
Local $px = 0
Local $pxges = 0
For $p = 0 To $Tiefe Step 1 ;p = BildNummern
For $x = 0 To $b / 2 ^ ($Tiefe - $p) Step 1
For $y = 0 To $h / 2 ^ ($Tiefe - $p) Step 1
$pxges += 1
Next
Next
Next
For $p = 0 To $Tiefe Step 1 ;p = BildNummern
For $x = 0 To $b / 2 ^ ($Tiefe - $p) Step 1
For $y = 0 To $h / 2 ^ ($Tiefe - $p) Step 1
Switch _Zufall($Nummer)
Case 0
$col = '0x' & Hex((255 / 2 ^ $p) * $Erhellen, 2) & '000000'
Case 1
$col = '0x' & Hex((255 / 2 ^ $p) * $Verdunkeln, 2) & 'FFFFFF'
EndSwitch
DllCall($ghGDIPDll, 'int', 'GdipBitmapSetPixel', 'hwnd', $bmp, 'int', $x, 'int', $y, 'dword', $col)
Next
Next
_GDIPlus_GraphicsDrawImageRectRect($bbuffer, $bmp, 0, 0, $b / 2 ^ ($Tiefe - $p), $h / 2 ^ ($Tiefe - $p), 0, 0, $b, $h)
Next
Local $_ptr, $_hbmp
Local $_hdc = _CreateNewBmp32($b, $h, $_ptr, $_hbmp)
Local $gra = _GDIPlus_GraphicsCreateFromHDC($_hdc)
_GDIPlus_GraphicsDrawImage($gra, $bmp2, 0, 0)
_GDIPlus_GraphicsDispose($gra)
_GDIPlus_GraphicsDispose($hBu)
_GDIPlus_GraphicsDispose($hBuffer)
_GDIPlus_GraphicsDispose($bbuffer)
_GDIPlus_BitmapDispose($bmp)
_GDIPlus_BitmapDispose($bmp2)
Local $a[3] = [$_hdc, $_hbmp, $_ptr]
Return $a
EndFunc ;==>_PerlinNoise
#ce
[/autoit] [autoit][/autoit] [autoit]#Region - Image Befehle (by Mars)
[/autoit] [autoit][/autoit] [autoit]Func _CreateImage($b, $h)
Local $ptr, $hdc, $hbmp
$hdc = _CreateNewBmp32($b, $h, $ptr, $hbmp)
Local $struct = DllStructCreate('int[5]')
DllStructSetData($struct, 1, $hdc, 1)
DllStructSetData($struct, 1, $b, 2)
DllStructSetData($struct, 1, $h, 3)
DllStructSetData($struct, 1, $ptr, 4)
DllStructSetData($struct, 1, $hbmp, 5)
Return $struct
EndFunc ;==>_CreateImage
Func _CreateImageRes($res)
Local $ptr, $hdc, $hbmp, $b, $h
$hdc = getDCfromRes32($res, $ptr, $hbmp, $b, $h)
Local $struct = DllStructCreate('int[5]')
DllStructSetData($struct, 1, $hdc, 1)
DllStructSetData($struct, 1, $b, 2)
DllStructSetData($struct, 1, $h, 3)
DllStructSetData($struct, 1, $ptr, 4)
DllStructSetData($struct, 1, $hbmp, 5)
Return $struct
EndFunc ;==>_CreateImageRes
Func _CreateImageSchrift($String, $Farbe = 0xFFFFFFFF, $Size_ = 5, $abs = 1)
Local $size = _GetSize($String, $Size_, $abs)
Local $b = $size[0]
Local $h = $size[1]
Local $ptr, $hbmp
Local $hdc = _CreateNewBmp32($b, $h, $ptr, $hbmp)
Local $hgr = _GDIPlus_GraphicsCreateFromHDC($hdc)
_GDIPlus_GraphicsClear($hgr, 0x00000000)
_GDIPlus_GraphicsDispose($hgr)
_DrawSchrift($hdc, $String, $Size_, $Farbe, $abs)
Local $struct = DllStructCreate('int[5]')
DllStructSetData($struct, 1, $hdc, 1)
DllStructSetData($struct, 1, $b, 2)
DllStructSetData($struct, 1, $h, 3)
DllStructSetData($struct, 1, $ptr, 4)
DllStructSetData($struct, 1, $hbmp, 5)
Return $struct
EndFunc ;==>_CreateImageSchrift
Func _DrawImage($hdc, $x, $y, $struct, $yoffset = 0)
_WinAPI_BitBlt($hdc, $x, $y + $yoffset, DllStructGetData($struct, 1, 2), DllStructGetData($struct, 1, 3), DllStructGetData($struct, 1, 1), 0, 0, $SRCCOPY)
EndFunc ;==>_DrawImage
Func _DrawImageStretch($hdc, $x, $y, $struct, $Zoom = 1, $yoffset = 0)
_WinAPI_StretchBlt($hdc, $x, $y, DllStructGetData($struct, 1, 2)*$Zoom, DllStructGetData($struct, 1, 3)*$Zoom, DllStructGetData($struct, 1, 1), 0, 0,DllStructGetData($struct, 1, 2), DllStructGetData($struct, 1, 3), $SRCCOPY)
EndFunc
Func _DrawImageTrans($hdc, $x, $y, $struct, $Zoom = 1, $yoffset = 0)
_GDI_AlphaBlend($hdc, $x, $y + $yoffset, DllStructGetData($struct, 1, 2)*$Zoom, DllStructGetData($struct, 1, 3)*$Zoom, DllStructGetData($struct, 1, 1), 0, 0, DllStructGetData($struct, 1, 2), DllStructGetData($struct, 1, 3), $h_AlphaStruct)
EndFunc ;==>_DrawImageTrans
Func _DeleteImage(ByRef $struct)
_Delete_Bitmap32(DllStructGetData($struct, 1, 1), DllStructGetData($struct, 1, 5))
$struct = 0
EndFunc ;==>_DeleteImage
Func _CopyImage($img)
Local $hDC_img = DllStructGetData($img, 1, 1)
Local $b_img = DllStructGetData($img, 1, 2)
Local $h_img = DllStructGetData($img, 1, 3)
Local $ret = _CreateImage($b_img, $h_img)
_DrawImage(DllStructGetData($ret, 1, 1), 0, 0, $img, 0)
Return $ret
EndFunc ;==>_CopyImage
Func _SaveImage($img)
Local $Pfad = FileSaveDialog('BildSpeichern', @ScriptDir, '(*,.png)', Default, Hex(Random(256, 16 ^ 3, 1), 3) & '.png')
If Not StringRight($Pfad, 4) = '.png' Then $Pfad &= '.png'
_GDIPlus_Startup()
Local $bm = _GDIPlus_BitmapCreateFromHBITMAP(DllStructGetData($img, 1, 5))
_GDIPlus_ImageSaveToFile($bm, $Pfad)
_GDIPlus_BitmapDispose($bm)
_GDIPlus_Shutdown()
EndFunc ;==>_Save
#EndRegion - Image Befehle (by Mars)
;EndRegion - Image Befehle (by Mars)
#Region
[/autoit] [autoit][/autoit] [autoit]Func _Exit()
_GDIPlus_Shutdown()
_WinAPI_ReleaseDC($hGUI, $hdc_GUI)
_DeleteImage($Backbuffer)
_DeleteImage($Perlin)
_DeleteImage($ImageSchrift_Zeit)
DllClose($h_NTDLL_DLL)
DllClose($h_MSIMG32_DLL)
DllClose($h_GDI32_DLL)
DllClose($h_OLE32_DLL)
DllClose($h_USER32_DLL)
DllClose($h_KERNEL32_DLL)
EndFunc
Func _Log($x, $y) ; Logarithmus zur Basis y
Return Log($x) / Log($y)
EndFunc ;==>Log2
Func _Betrag($a)
If $a > 0 Then Return $a
Return -$a
EndFunc ;==>_Betrag
Func _Min($a, $b)
If $a > $b Then Return $b
Return $a
EndFunc ;==>_Min
Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
If ($hWnd = $hGUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
EndFunc ;==>WM_NCHITTEST
Func _DrawSchrift($hdc, $String, $px, $Farbe = 0xFFFF0000, $abs = 1)
Local $FontPng = _SchriftRes($px)
Local $Font
Local $ptr, $hbmp, $imgBreite, $imgHoehe
Local $hDC_Font = getDCfromRes32($FontPng, $ptr, $hbmp, $imgBreite, $imgHoehe)
_Farbe($ptr, $Farbe, $imgBreite * $imgHoehe)
Local $l = StringLen($String)
Local $s = ''
Local $x = 0, $y = 0, $nr = 0
For $i = 1 To $l Step 1
$s = StringMid($String, $i, 1)
If $s = '|' Then
$y += $px + $abs
$x = 0
Else
$nr = _GetNr($s)
If $nr <> 36 Then _WinAPI_StretchBlt($hdc, $x, $y, $px, $px, $hDC_Font, $nr * $px, 0, $px, $px, $SRCCOPY)
$x += $px + $abs
EndIf
Next
_Delete_Bitmap32($hDC_Font, $hbmp)
EndFunc ;==>_DrawSchrift
Func _GetSize($a, $px, $abs = 1)
Local $l = StringLen($a)
Local $s = ''
Local $c = 0, $c2 = 0, $c3 = 0
For $i = 1 To $l Step 1
$c += 1
If $c >= $c2 Then $c2 = $c
$s = StringMid($a, $i, 1)
If $s = '|' Then
$c = 0
$c3 += 1
EndIf
Next
Local $ret[2] = [$c2 * ($px + $abs), ($c3 + 1) * ($px + $abs)] ;5px für den Buchstaben und einer für den Abstand, $c3 wird erhöht, da Zeile 0 sonst nicht mitgezählt wird.
Return $ret
EndFunc ;==>_GetSize
Func _GetNr($a) ;Gibt die Nummer des Zeichens aus
Local $b[36 + 23] = ['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', '_', '.', ';', 'ä', 'ö', 'ü', '-', '§', '$', '%', '&', '#', '>', '<', '[', ']', '(', ')', '"', "'", '=', '+', ':']
For $i = 0 To 35 + 23 Step 1
If $a = $b[$i] Then Return $i
Next
Return 36 + 23
EndFunc ;==>_GetNr
Func _Farbe($ptr, $col, $px)
Local $_Struct = DllStructCreate('int[' & $px & ']', $ptr)
For $i = 0 To $px Step 1
If DllStructGetData($_Struct, 1, $i) = 0xFFFFFFFF Then
DllStructSetData($_Struct, 1, $col, $i)
Else
DllStructSetData($_Struct, 1, 0x00000000, $i)
EndIf
Next
EndFunc ;==>_Farbe
Func _SchriftRes($px) ;Enthält die png Bilder der Schriften als Ressourcen.
Switch $px
Case 4
Return '0x89504E470D0A1A0A0000000D49484452000000EC000000040100000000A5BFEE56000000874944415468DE017C0083FF00FEFEFFF9FF98FDFFFFFF99999FEFF8F8FFFF0006660BF996C3BD7EA4F000009989888921A8BD9999C299B693231ACF999B000FF90BF42F3CC3A5A4044000FA89EEBF21E8BB9FAE3296B6FC2C7F393FFD004F996B024F3CC3A5000E00009FFEF8F9F69F9BF8D9F2F6F92FFFF2FF1F1FF449FF0BF996C3BD7E00F440068A47638487EBE40000000049454E44AE426082'
Case 5
Return '0x89504E470D0A1A0A0000000D49484452000001270000000501000000002F321765000000C94944415478DA01BE0041FF00FFFFEFFFF1FFE30DC7FFFFFFF8C6318FFDFFC3F0FFFFF0000A52815FC92AC0EFD7F9440000008C6118423120630AE6318C6048C6B1884410C21F8C6330001FFC4150265F21303A1544F908008DA11F7A1F207D0AD6318FFE48C6AEFFC5F7D3F10FE35000118C5D5F908A1E303A1400038000FC6118427120630ACE3F948248AAB1240500FC311C7F90009F8C4150493F21303A1400F908008FFFEFC3F1FBE3F8C7F0EC7E4F93F127FFFF93FF0FC3FF9091FFC15FA64AC0EFD7F80000002DA25C98C2B780160000000049454E44AE426082'
EndSwitch
EndFunc ;==>_SchriftRes
Func _MemGlobalAlloc($iBytes, $iFlags = 0)
Local $aResult = DllCall($h_KERNEL32_DLL, 'handle', 'GlobalAlloc', 'uint', $iFlags, 'ulong_ptr', $iBytes)
Return $aResult[0]
EndFunc ;==>_MemGlobalAlloc
Func _MemGlobalLock($hMem)
Local $aResult = DllCall($h_KERNEL32_DLL, 'ptr', 'GlobalLock', 'handle', $hMem)
Return $aResult[0]
EndFunc ;==>_MemGlobalLock
Func _MemGlobalUnlock($hMem)
Local $aResult = DllCall($h_KERNEL32_DLL, 'bool', 'GlobalUnlock', 'handle', $hMem)
Return $aResult[0]
EndFunc ;==>_MemGlobalUnlock
Func _IsPressed($a)
Local $b = DllCall($h_USER32_DLL, "short", "GetAsyncKeyState", "int", '0x' & $a)
Return BitAND($b[0], 0x8000) <> 0
EndFunc ;==>_IsPressed
Func _Delete_Bitmap32($hdc, $hbmp)
_WinAPI_DeleteObject($hbmp)
_WinAPI_DeleteDC($hdc)
EndFunc ;==>_Delete_Bitmap32
Func _CreateNewBmp32($iWidth, $iHeight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe DC und ptr und handle auf die Bitmapdaten
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $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
Local $adib = DllCall($h_GDI32_DLL, 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, '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 getDCfromRes32($res, ByRef $ptr, ByRef $hbmp, ByRef $iwidth_file32, ByRef $iheight_file32);Erstellt eine 32-Bit Bitmap von Ressource Daten. + Breite und Höhe werden ermittelt
_GDIPlus_Startup()
Local $hBitmap = Load_BMP_From_Mem($res)
$hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
$iwidth_file32 = _GDIPlus_ImageGetWidth($hBitmap)
$iheight_file32 = _GDIPlus_ImageGetHeight($hBitmap)
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $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_file32)
DllStructSetData($tBMI, "Height", -$iheight_file32) ;minus =standard = bottomup
DllStructSetData($tBMI, "Planes", 1)
DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
Local $adib = DllCall($h_GDI32_DLL, 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, 'ptr*', 0, 'ptr', 0, 'uint', 0)
_WinAPI_SelectObject($hcdc, $adib[0])
; copy the content of the bitmap into the buffer ...
_WinAPI_GetDIBits($hcdc, $hbmp, 0, $iheight_file32, $adib[4], DllStructGetPtr($tBMI), $DIB_RGB_COLORS)
$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
;_arraydisplay($adib)
_WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
Return $hcdc ;DC der Bitmap zurückgeben
EndFunc ;==>getDCfromRes32
Func Load_BMP_From_Mem($pic)
Local $memBitmap, $len, $tMem, $hImage, $hData, $pData, $hStream, $hBitmapFromStream
$memBitmap = Binary($pic)
$len = BinaryLen($memBitmap)
$hData = _MemGlobalAlloc($len, 0x0002)
$pData = _MemGlobalLock($hData)
$tMem = DllStructCreate("byte[" & $len & "]", $pData)
DllStructSetData($tMem, 1, $memBitmap)
_MemGlobalUnlock($hData)
$hStream = _WinAPI_CreateStreamOnHGlobal($pData)
$hBitmapFromStream = _GDIPlus_BitmapCreateFromStream($hStream)
$tMem = ""
Return $hBitmapFromStream
EndFunc ;==>Load_BMP_From_Mem
Func _WinAPI_StretchBlt($hDestDC, $iXDest, $iYDest, $iWidthDest, $iHeightDest, $hSrcDC, $iXSrc, $iYSrc, $iWidthSrc, $iHeightSrc, $iRop)
DllCall('gdi32.dll', 'int', 'StretchBlt', 'hwnd', $hDestDC, 'int', $iXDest, 'int', $iYDest, 'int', $iWidthDest, 'int', $iHeightDest, 'hwnd', $hSrcDC, 'int', $iXSrc, 'int', $iYSrc, 'int', $iWidthSrc, 'int', $iHeightSrc, 'dword', $iRop)
EndFunc ;==>_WinAPI_StretchBlt
Func _GDI_AlphaBlend_GetStruct($Alpha = 255)
Local $struct = DllStructCreate($tagBLENDFUNCTION)
DllStructSetData($struct, 1, 0) ; 0 = AC_SRC_OVER
DllStructSetData($struct, 2, 0) ; 0 "Must be Zero"
DllStructSetData($struct, 3, $Alpha) ; Alpha fürs ganze Bild
DllStructSetData($struct, 4, 1) ; 1 = Bild enthält einen Alphakanal
Local $data = DllStructCreate("dword", DllStructGetPtr($struct))
$data = DllStructGetData($data, 1)
Return $data
EndFunc ;==>_GDI_AlphaBlend_GetStruct
Func _GDI_AlphaBlend($hDCDest, $nXOriginDest, $nYOriginDest, $nWidthDest, $nHeightDest, $hDCSrc, $nXOriginSrc, $nYOriginSrc, $nWidthSrc, $nHeightSrc, $blendFunction)
DllCall($h_MSIMG32_DLL, 'int', 'AlphaBlend', _
'ptr', $hDCDest, _ ; // handle to destination DC
'int', $nXOriginDest, _ ; // x-coord of upper-left corner
'int', $nYOriginDest, _ ; // y-coord of upper-left corner
'int', $nWidthDest, _ ; // destination width
'int', $nHeightDest, _ ; // destination height
'ptr', $hDCSrc, _ ; // handle to source DC
'int', $nXOriginSrc, _ ; // x-coord of upper-left corner
'int', $nYOriginSrc, _ ; // y-coord of upper-left corner
'int', $nWidthSrc, _ ; // source width
'int', $nHeightSrc, _ ; // source height
'dword', $blendFunction);$blendFunction) ; // alpha-blending function
EndFunc ;==>_GDI_AlphaBlend
Func _WinAPI_CreateStreamOnHGlobal($hGlobal = 0, $fDeleteOnRelease = True)
Local $aResult = DllCall($h_OLE32_DLL, "int", "CreateStreamOnHGlobal", "hwnd", $hGlobal, "int", $fDeleteOnRelease, "ptr*", 0)
Return $aResult[3]
EndFunc ;==>_WinAPI_CreateStreamOnHGlobal
Func _GDIPlus_BitmapCreateFromStream($pStream)
Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
Return $aResult[2]
EndFunc ;==>_GDIPlus_BitmapCreateFromStream
Func _C($a, $b = 0) ;Gibt x/y Koords für ein Fenster damit es zentriert ist.
If $b Then Return @DesktopWidth / 2 - $a / 2 ; Wenn b dann x
Return @DesktopHeight / 2 - $a / 2 ; Sonst y
EndFunc ;==>_C
#EndRegion
[/autoit]Die Zeiten sind etwa 2.5 - 3 Mal so schnell.
Viel Spaß
Vorschläge können einfach gepostet werden. (Also keine "geheime" Auswertung^^)
Mars(i)