Bild drehen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

die diskussion hatten wir schon mal, wie man an den pointer eines images kommt.

weiter oben hab ich nen link zu dem thread geschrieben, wo die diskussion war,
und in dem übrigens Stefan ganz prima ASM-Routinen gepostet hatte.

schau nach, irgendwo da stehts.

ich habs net im kopf, weil ich im leben seltener images verwendet habe, als mir die nase gebrochen.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Ich suche aber eine flotte simple Methode ohne ASM oder komplexeres rumgepointere um an den Speicherbereich zu kommen. Daher hab ich eben die WinAPI Methode benutzt und würde diese empfehlen, da man dort den Speicherbereich von vorne rein hat und aus dieser und einigen Infos dann das Image bastelt. Die Info liegen von Vorne herein offen, das ist es, was ich daran bevorzuge.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

da magst du ja recht haben, es ist aber plattformspezifisch. ;)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

@Sunny & Kaeru Gaman ...

auha, .... da hab ich wohl mit meiner Anfrage 'ne Grundsatzdiskusion von Zaun getreten ... :oops:
Aber was das schöne am Proggen ist ... letztendlich findet man ja doch immer wieder zusammen. :allright:

Aber falls da jemand von Euch noch ein konkretes Beispiel für mich hätte, wie ich das nun per Pointer und direktem Speicherzugriff machen könnte (also die Pixelmanipulation beschleunigen), wäre ich sehr dankbar (da ich durch diesen ganzen Pointerkram noch nicht so ganz durchblicke).

@Kaeru:
Kaeru Gaman hat geschrieben:@PureLust
((Sorry, ich grins mal, ich muß bei deinem namen immer an die "geile" Shampoo-Werbung denken))
Danke für den Tipp !!! :allright: (Ergebnis, siehe links !!!) :D
Kaeru Gaman hat geschrieben:@vielleichicht hilft dir dieses "ältere" thema:
http://forums.purebasic.com/german/view ... 51&start=0
Das hat mir leider auch nicht weiter geholfen. :(
1. funktioniert die von Dir angesprochene Methode ( *Spr = DrawingBuffer()) leider nicht bei Images, und zum
2. werde ich aus Stefans Art und Weise die Speicherposition des Sprites zu ermitteln nicht ganz schlau:

Code: Alles auswählen

  SpriteWidth=*Sprite\Width-1 
  SpriteHeight=*Sprite\Height-1 
  
  StartX=*Sprite\ClipX 
  StartY=*Sprite\ClipY 
  EndX=SpriteWidth+StartX 
  EndY=SpriteHeight+StartY 
  
  SpriteWidth2=(SpriteWidth)/2+StartX 
  SpriteHeight2=(SpriteHeight)/2+StartY 
  
  ScreenWidth=_ScreenWidth()-1 
  ScreenHeight=_ScreenHeight()-1 
  
  *SpriteDDS.IDirectDrawSurface7=*Sprite\Sprite 
  *DestDDS.IDirectDrawSurface7=GetCurrentBuffer() 
  
  SpriteDDSD2.DDSURFACEDESC2 
  DestDDSD2.DDSURFACEDESC2 
  
  SpriteDDSD2\dwSize=SizeOf(DDSURFACEDESC2) 
  DestDDSD2\dwSize=SizeOf(DDSURFACEDESC2) 
  
  *SpriteDDS\Lock(0,SpriteDDSD2,#DDLOCK_WAIT,0) 
  *DestDDS\Lock(0,DestDDSD2,#DDLOCK_WAIT,0) 
  
  SrcPitch=SpriteDDSD2\lPitch 
  DestPitch=DestDDSD2\lPitch 
  
==>  SrcAddr=SpriteDDSD2\lpSurface 
==>  DestAddr=DestDDSD2\lpSurface
Mal ganz abgesehen davon, ob sich diese Methode überhaupt auf ein Image übertragen lässt... :roll:

Aber solltest Du da irgend eine konkrete Idee haben, wie das auf Images übertragbar wäre, wäre das natürlich klasse. :D

Big ThanXXX und Greetz, Luke.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
Mischa
Beiträge: 152
Registriert: 29.08.2004 06:52
Wohnort: Hellhorst

Beitrag von Mischa »

@PureLust

Du solltest Dir mal die beiden UserLibs

"Rotate" und "Effects" auf PureArea.net anschauen, die machen das
auf etwas schnellere Art. Zumindest bei den "Effects" sollte der
source beiliegen, der für Dich genügend Informationsgehalt zur
schnellen Bildmanipulation enthalten sollte.

Deine Rotationsroutine ist übrigens sehr nett, netter als meine
stumpfe Lösung. :wink: (Allerdings "noch" zu langsam)

Gruß,
Mischa
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

PureLust hat geschrieben:Danke für den Tipp !!! :allright: (Ergebnis, siehe links !!!) :D
ya, is mir auch sofort ins auge geprungen... ein echter hingucker... :allright:
PureLust hat geschrieben:2. werde ich aus Stefans Art und Weise die Speicherposition des Sprites zu ermitteln nicht ganz schlau:
schreib ihm doch ne PN, er kann dir am besten dabei helfen...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

Hi Mischa, ...

dank Deines klasse Tips und Deinem 'Effects' Source (*Big ThanXXX* :allright: ), hab ich die Rotationsroutine nun durch WinAPI-Befehle 'ein klein wenig' beschleunigen können. :D

Um besser zwischen der original Routine mit reinen PB-Befehlen (siehe erste Seite in diesem Thread) und der neuen Routine mit WinAPI-Aufrufen (dadurch leider nicht Plattform unabhängig /:-> ) habe ich sowohl in die neue als auch noch nachträglich in die alte Routine eine min/max FPS Routine eingebaut.

Code: Alles auswählen

Zum Vergeich (auf meinem 2.8GHz P4):

Alte Routine - mit  Filter :  19 -  98 FPS  (mit reinen PB-Befehlen)
Alte Routine - ohne Filter :  20 - 121 FPS  (also Plattform unabhängig)

Neue Routine - mit  Filter : 131 - 327 FPS  (mit WinAPI Aufrufen)
Neue Routine - ohne Filter : 219 - 392 FPS  (also NICHT Plattform unabhängig)
Wie gesagt: Die neue ist nur 'ein klein wenig' schneller !!! :D

Anbei mal der neue Code:

Wie immer mit Kommentaren zum besseren Verständnis.

Code: Alles auswählen

DefType.w OrigBreite,OrigHoehe,OrigXDrehpunkt,OrigYDrehpunkt,ZielBreite,ZielHoehe,Rand,x,y

Structure _LTI_BITMAPINFO 
  bmiHeader.BITMAPINFOHEADER 
  bmiColors.RGBQUAD[1] 
EndStructure

; Standardvariablen definieren
#GFX_Mittelwertfilter = 1
OrigBreite=200
OrigHoehe=200
OrigXDrehpunkt=40
OrigYDrehpunkt=45
ZielBreite=OrigBreite
ZielHoehe=OrigHoehe
Rand=20
Filterung.b=0
MaxFPS = 0
MinFPS = 999
Dim OrigPoint.l(OrigBreite+1,OrigHoehe+1)
Dim ZielPoint.l(ZielBreite-1,ZielHoehe-1)

If OpenWindow(0,10,10,OrigBreite*2+Rand*3,OrigHoehe+Rand*2,0," 2D Image-Rotation  <ESC>-Ende   <Space>-Pause   <F>-Filter")
   If CreateImage(1,OrigBreite,OrigHoehe)
      ; original Ausgangsbild erzeugen
      If StartDrawing(ImageOutput())
         Box(1,1,OrigBreite-2,OrigHoehe-2,RGB(255,255,255))
         Box(20,30,OrigBreite-40,30,RGB(20,200,200))
         Circle(OrigXDrehpunkt,OrigYDrehpunkt,4,RGB(0,0,255))
         Circle(OrigXDrehpunkt,OrigYDrehpunkt,2,RGB(255,255,255))
         Circle(40,OrigHoehe-41,30,RGB(200,33,33))
         ; Daten des Originalbildes in einem Array zwischenspeichern
         For x.w = 1 To OrigBreite
            For y.w = 1 To OrigHoehe
                OrigPointRGB.l=Point(x-1,y-1)
                ; Da die später benutzte WinAPI-Routine die Daten im BGR statt RGB-Format benötigt, werden die RGB-Werte in BGR-Werte umgewandelt
                OrigPoint(x,y)=RGB(Blue(OrigPointRGB),Green(OrigPointRGB),Red(OrigPointRGB))
            Next y
         Next x
         StopDrawing()
      EndIf
      If StartDrawing(WindowOutput())
         Hintergrundfarbe = Point(1,1)
         HintergrundfarbeBGR = RGB(Blue(Hintergrundfarbe),Green(Hintergrundfarbe),Red(Hintergrundfarbe))
         ; Im Bildpuffer einen Rahmen in Hintergrundfarbe um das Bild legen (für Filter)
         For x=0 To OrigBreite : OrigPoint(x,0)=Hintergrundfarbe : OrigPoint(x,OrigHoehe+1)=Hintergrundfarbe  : Next x
         For Y=0 To OrigHoehe  : OrigPoint(0,y)=Hintergrundfarbe : OrigPoint(OrigBreite+1,y)=Hintergrundfarbe : Next y         
         ; Originalbild auf Fenster ausgeben
         OrigImageID=UseImage(1)
         DrawImage(OrigImageID,Rand,Rand)
         StopDrawing()
      EndIf
      If CreateImage(2,ZielBreite,ZielHoehe)

         hdc=GetDC_(GetDesktopWindow_())
         hBmp=UseImage(2)
         bmi._LTI_BITMAPINFO 
         bmi\bmiHeader\biSize   = SizeOf(BITMAPINFOHEADER) 
         bmi\bmiHeader\biWidth  = ZielBreite 
         bmi\bmiHeader\biHeight = ZielHoehe
         bmi\bmiHeader\biPlanes = 1 
         bmi\bmiHeader\biBitCount = 32 
         bmi\bmiHeader\biCompression = #BI_RGB 

         DisableDebugger ; Debugger ausschalten, falls nötig
         Repeat
            StartTimer = ElapsedMilliseconds()
            For w = 0 To 359
               Winkel.f = 3.141/180*w
               ; mehrfach benutzte Berechnungen puffern
               SinWinkel.f = Sin(Winkel)
               CosWinkel.f = Cos(Winkel)
               ZielImageID=UseImage(2)

               If StartDrawing(ImageOutput())
                  For x.w = 1 To ZielBreite
                     ; mehrfach benutzte Berechnungen puffern
                     xSinWinkel.f = (x-OrigXDrehpunkt)*SinWinkel
                     xCosWinkel.f = (x-OrigXDrehpunkt)*CosWinkel
                     For y.w = 1 To ZielHoehe
                         zx.f=(xCosWinkel-(y-OrigYDrehpunkt)*SinWinkel)+OrigXDrehpunkt
                         zy.f=(xSinWinkel+(y-OrigYDrehpunkt)*CosWinkel)+OrigYDrehpunkt
                         Select Filterung 
                         Case #GFX_Mittelwertfilter
                            ; Berechnung mit Filter
                            If zx>0 And zx<OrigBreite+1 And zy>0 And zy<OrigHoehe+1
                               zxi = Int(zx+0.5)
                               zyi = Int(zy+0.5)
                               PixelFarbe1 = OrigPoint(zxi,zyi)
                               If zx<zxi
                                  PixelFarbe2 = OrigPoint(zxi-1,zyi)
                               Else
                                  PixelFarbe2 = OrigPoint(zxi+1,zyi)
                               EndIf
                               Gewichtung2.f=Abs(zx-zxi)
                               If zy>zyi
                                  PixelFarbe3 = OrigPoint(zxi,zyi+1)
                               Else
                                  PixelFarbe3 = OrigPoint(zxi,zyi-1)
                               EndIf
                               Gewichtung3.f=Abs(zy-zyi)
                               Gewichtung1.f=1-Gewichtung2-Gewichtung3
                               ; Pixelgewichtung berechnen
                               PixelRed=Red(PixelFarbe1)*Gewichtung1+Red(PixelFarbe2)*Gewichtung2+Red(PixelFarbe3)*Gewichtung3
                               PixelGreen=Green(PixelFarbe1)*Gewichtung1+Green(PixelFarbe2)*Gewichtung2+Green(PixelFarbe3)*Gewichtung3
                               PixelBlue=Blue(PixelFarbe1)*Gewichtung1+Blue(PixelFarbe2)*Gewichtung2+Blue(PixelFarbe3)*Gewichtung3
                               ZielPoint(ZielHoehe-y,x-1)=RGB(PixelRed,PixelGreen,PixelBlue)
                            Else
                               ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR
                            EndIf
                         Default
                            ; Berechnung ohne Filter
                            If zx>=1 And zx<OrigBreite+1 And zy>=1 And zy<OrigHoehe+1 
                               ZielPoint(ZielHoehe-y,x-1)=OrigPoint(Int(zx),Int(zy))
                            Else
                               ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR
                            EndIf
                         EndSelect
                      Next y
                  Next x
                  StopDrawing()
                  SetDIBits_(hdc,hBmp,0,ZielHoehe,ZielPoint(),bmi,#DIB_RGB_COLORS)
               EndIf                 
               If StartDrawing(WindowOutput())
                  ; gedrehtes Image auf Fenster ausgeben
                  DrawImage(ZielImageID,rand*2+OrigBreite,Rand)
                  StopDrawing()
               EndIf
               Event=WindowEvent()                             
               If Event = #WM_KEYDOWN
                  ; Tastendrücke auswerten
                  If EventwParam() = #VK_SPACE
                     Repeat
                     Event=WaitWindowEvent()
                     Until Event = #WM_KEYDOWN
                  ElseIf EventwParam() = #VK_F
                     Filterung = #GFX_Mittelwertfilter-Filterung
                  ElseIf EventwParam() = #VK_ESCAPE
                     Break 2
                  EndIf
                  ResetFPS = 1
               EndIf
            If w%20=19
               ; Berechnung der FPS (Bilder pro Sekunde)
               If ResetFPS
                  MaxFPS = 0
                  MinFPS = 999
                  ResetFPS = 0
               Else
                  AktFPS = 20000/(ElapsedMilliseconds()-StartTimer+1)
                  If AktFPS < MinFPS : MinFPS = AktFPS : EndIf
                  If AktFPS > MaxFPS : MaxFPS = AktFPS : EndIf
                  SetWindowTitle(0," 2D Image-Rotation  <ESC>-Ende   <Space>-Pause   <F>-Filter    "+Str(MinFPS)+"-"+Str(MaxFPS)+" FPS")
               EndIf
               StartTimer = ElapsedMilliseconds()
            EndIf
            Next w
         ForEver
      ReleaseDC_(GetDesktopWindow_(),hdc)
      EnableDebugger  ; Debugger wieder aktivieren
      EndIf
   EndIf
EndIf
End
Tastenkommandos:
<F> - Filter ein/aus
<Space> - Pause
<Esc> - Programm beenden

(Criticism and Comments are welcome) :wink:

Greetz, Luke.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Super Code :allright:
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
PureLust
Beiträge: 1145
Registriert: 21.07.2005 00:02
Computerausstattung: Hab aktuell im Grunde nur noch 'nen Lenovo Yoga 2 Pro im Einsatz.
Wohnort: am schönen Niederrhein

Beitrag von PureLust »

Hab die Routine aus gegebenem Anlass mal PB 4.10 kompatibel gemacht und gleichzeitig ein wenig die Pausefunktion verfeinert.
Nun kann man also auch bei stehendem Bild den Filter an- bzw. abschalten um den Unterschied besser sehen zu können.

Code: Alles auswählen

Define.w OrigBreite,OrigHoehe,OrigXDrehpunkt,OrigYDrehpunkt,ZielBreite,ZielHoehe,Rand,x,y 

Structure _LTI_BITMAPINFO 
  bmiHeader.BITMAPINFOHEADER 
  bmiColors.RGBQUAD[1] 
EndStructure 

; Standardvariablen definieren 
#GFX_Mittelwertfilter = 1 
OrigBreite=200 
OrigHoehe=200 
OrigXDrehpunkt=40 
OrigYDrehpunkt=45 
ZielBreite=OrigBreite 
ZielHoehe=OrigHoehe 
Rand=20 
Filterung.b=0 
MaxFPS = 0 
MinFPS = 999 
Dim OrigPoint.l(OrigBreite+1,OrigHoehe+1) 
Dim ZielPoint.l(ZielBreite-1,ZielHoehe-1) 

If OpenWindow(0,10,10,OrigBreite*2+Rand*3,OrigHoehe+Rand*2," 2D Image-Rotation  <ESC>-Ende   <Space>-Pause   <F>-Filter") 
   If CreateImage(1,OrigBreite,OrigHoehe) 
      ; original Ausgangsbild erzeugen 
      If StartDrawing(ImageOutput(1)) 
         Box(1,1,OrigBreite-2,OrigHoehe-2,RGB(255,255,255)) 
         Box(20,30,OrigBreite-40,30,RGB(20,200,200)) 
         Circle(OrigXDrehpunkt,OrigYDrehpunkt,4,RGB(0,0,255)) 
         Circle(OrigXDrehpunkt,OrigYDrehpunkt,2,RGB(255,255,255)) 
         Circle(40,OrigHoehe-41,30,RGB(200,33,33)) 
         ; Daten des Originalbildes in einem Array zwischenspeichern 
         For x.w = 1 To OrigBreite 
            For y.w = 1 To OrigHoehe 
                OrigPointRGB.l=Point(x-1,y-1) 
                ; Da die später benutzte WinAPI-Routine die Daten im BGR statt RGB-Format benötigt, werden die RGB-Werte in BGR-Werte umgewandelt 
                OrigPoint(x,y)=RGB(Blue(OrigPointRGB),Green(OrigPointRGB),Red(OrigPointRGB)) 
            Next y 
         Next x 
         StopDrawing() 
      EndIf 
      If StartDrawing(WindowOutput(0)) 
         Hintergrundfarbe = Point(1,1) 
         HintergrundfarbeBGR = RGB(Blue(Hintergrundfarbe),Green(Hintergrundfarbe),Red(Hintergrundfarbe)) 
         ; Im Bildpuffer einen Rahmen in Hintergrundfarbe um das Bild legen (für Filter) 
         For x=0 To OrigBreite : OrigPoint(x,0)=Hintergrundfarbe : OrigPoint(x,OrigHoehe+1)=Hintergrundfarbe  : Next x 
         For Y=0 To OrigHoehe  : OrigPoint(0,y)=Hintergrundfarbe : OrigPoint(OrigBreite+1,y)=Hintergrundfarbe : Next y          
         ; Originalbild auf Fenster ausgeben 
         DrawImage(ImageID(1),Rand,Rand) 
         StopDrawing() 
      EndIf 
      If CreateImage(2,ZielBreite,ZielHoehe) 

         hdc=GetDC_(GetDesktopWindow_()) 
         hBmp=ImageID(2) 
         bmi._LTI_BITMAPINFO 
         bmi\bmiHeader\biSize   = SizeOf(BITMAPINFOHEADER) 
         bmi\bmiHeader\biWidth  = ZielBreite 
         bmi\bmiHeader\biHeight = ZielHoehe 
         bmi\bmiHeader\biPlanes = 1 
         bmi\bmiHeader\biBitCount = 32 
         bmi\bmiHeader\biCompression = #BI_RGB 

         DisableDebugger ; Debugger ausschalten, falls nötig
         rotate = #True		; Rotate-Flag
         w      = 0			; Drehwinkel
         quit   = #False	; Quit-Flag
         
         Repeat 
            StartTimer = ElapsedMilliseconds()
            If rotate
            	w +1
            	If w > 359 : w = 0 : EndIf
            EndIf

            Winkel.f = 3.141/180*w 
            ; mehrfach benutzte Berechnungen puffern 
            SinWinkel.f = Sin(Winkel) 
            CosWinkel.f = Cos(Winkel) 
            ZielImageID=ImageID(2) 

            If StartDrawing(ImageOutput(2)) 
               For x.w = 1 To ZielBreite 
                  ; mehrfach benutzte Berechnungen puffern 
                  xSinWinkel.f = (x-OrigXDrehpunkt)*SinWinkel 
                  xCosWinkel.f = (x-OrigXDrehpunkt)*CosWinkel 
                  For y.w = 1 To ZielHoehe 
                      zx.f=(xCosWinkel-(y-OrigYDrehpunkt)*SinWinkel)+OrigXDrehpunkt 
                      zy.f=(xSinWinkel+(y-OrigYDrehpunkt)*CosWinkel)+OrigYDrehpunkt 
                      Select Filterung 
                      Case #GFX_Mittelwertfilter 
                         ; Berechnung mit Filter 
                         If zx>0 And zx<OrigBreite+1 And zy>0 And zy<OrigHoehe+1 
                            zxi = Int(zx+0.5) 
                            zyi = Int(zy+0.5) 
                            PixelFarbe1 = OrigPoint(zxi,zyi) 
                            If zx<zxi 
                               PixelFarbe2 = OrigPoint(zxi-1,zyi) 
                            Else 
                               PixelFarbe2 = OrigPoint(zxi+1,zyi) 
                            EndIf 
                            Gewichtung2.f=Abs(zx-zxi) 
                            If zy>zyi 
                               PixelFarbe3 = OrigPoint(zxi,zyi+1) 
                            Else 
                               PixelFarbe3 = OrigPoint(zxi,zyi-1) 
                            EndIf 
                            Gewichtung3.f=Abs(zy-zyi) 
                            Gewichtung1.f=1-Gewichtung2-Gewichtung3 
                            ; Pixelgewichtung berechnen 
                            PixelRed=Red(PixelFarbe1)*Gewichtung1+Red(PixelFarbe2)*Gewichtung2+Red(PixelFarbe3)*Gewichtung3 
                            PixelGreen=Green(PixelFarbe1)*Gewichtung1+Green(PixelFarbe2)*Gewichtung2+Green(PixelFarbe3)*Gewichtung3 
                            PixelBlue=Blue(PixelFarbe1)*Gewichtung1+Blue(PixelFarbe2)*Gewichtung2+Blue(PixelFarbe3)*Gewichtung3 
                            ZielPoint(ZielHoehe-y,x-1)=RGB(PixelRed,PixelGreen,PixelBlue) 
                         Else 
                            ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR 
                         EndIf 
                      Default 
                         ; Berechnung ohne Filter 
                         If zx>=1 And zx<OrigBreite+1 And zy>=1 And zy<OrigHoehe+1 
                            ZielPoint(ZielHoehe-y,x-1)=OrigPoint(Int(zx),Int(zy)) 
                         Else 
                            ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR 
                         EndIf 
                      EndSelect 
                   Next y 
               Next x 
               StopDrawing() 
               SetDIBits_(hdc,hBmp,0,ZielHoehe,ZielPoint(),bmi,#DIB_RGB_COLORS) 
            EndIf                  
            If StartDrawing(WindowOutput(0)) 
               ; gedrehtes Image auf Fenster ausgeben 
               DrawImage(ZielImageID,rand*2+OrigBreite,Rand) 
               StopDrawing() 
            EndIf 
         Event=WindowEvent()                              
         If Event = #WM_KEYDOWN 
            ; Tastendrücke auswerten 
            If EventwParam() = #VK_SPACE 
               rotate = 1 - rotate
            ElseIf EventwParam() = #VK_F 
               Filterung = #GFX_Mittelwertfilter-Filterung 
            ElseIf EventwParam() = #VK_ESCAPE 
               quit = #True
            EndIf 
            ResetFPS = 1 
         EndIf 
         If w%20=19 
            ; Berechnung der FPS (Bilder pro Sekunde) 
            If ResetFPS 
               MaxFPS = 0 
               MinFPS = 999 
               ResetFPS = 0 
            Else 
               AktFPS = 20000/(ElapsedMilliseconds()-StartTimer+1) 
               If AktFPS < MinFPS : MinFPS = AktFPS : EndIf 
               If AktFPS > MaxFPS : MaxFPS = AktFPS : EndIf 
               SetWindowTitle(0," 2D Image-Rotation  <ESC>-Ende   <Space>-Pause   <F>-Filter    "+Str(MinFPS)+"-"+Str(MaxFPS)+" FPS") 
            EndIf 
            StartTimer = ElapsedMilliseconds() 
         EndIf 
         Until quit 
      ReleaseDC_(GetDesktopWindow_(),hdc) 
      EnableDebugger  ; Debugger wieder aktivieren 
      EndIf 
   EndIf 
EndIf 
End
Also ... wer's brauchen kann. ;)

Gruß, PL.
[Dynamic-Dialogs] - komplexe dynamische GUIs einfach erstellen
[DeFlicker] - Fenster flimmerfrei resizen
[WinFX] - Window Effekte (inkl. 'durchklickbares' Window)
Antworten