Hallo,
bei der Suche nach Möglichkeiten Images zu manipulieren (Filter wie Blur, Sharp usw.) bin ich auf das Thema 'Plane Deformation' gestossen.
Das schaut interessant und eigentlich ganz einfach aus aber bei mir kommt immer nur Pixelmatsch raus!
plane-deformations-are-fun
deform
Ich vermute mal das liegt am unterschiedlichen Handling von SIN/COS/ATAN.
Kann mir da bitte jemand mit ein paar Zeilen in PB auf die Spünge helfen?
Danke.
2D Plane Deformation ?
Re: 2D Plane Deformation ?
Ich hab dir mal einen kleinen Code zusammengeworfen.
Einfach ist es, solange du mit den Formeln experimentierst.
Komplizierter wird es, wenn du damit etwas bestimmtes erreichen willst
Achtung, der Code ist so gut wie nicht optimiert, am besten den Debugger zum testen ausschalten.
Es stehen jedoch Tipps drinnen, wie du mehr Geschwindigkeit herausholen kannst.
Einfach ist es, solange du mit den Formeln experimentierst.
Komplizierter wird es, wenn du damit etwas bestimmtes erreichen willst
Achtung, der Code ist so gut wie nicht optimiert, am besten den Debugger zum testen ausschalten.
Es stehen jedoch Tipps drinnen, wie du mehr Geschwindigkeit herausholen kannst.
Code: Alles auswählen
UseJPEGImageDecoder()
InitSprite()
InitNetwork()
InitKeyboard()
#xres=800
#yres=600
#targetfile="image.jpg"
OpenScreen(#xres,#yres,32,"Plane Deformation",#PB_Screen_SmartSynchronization,10)
StartDrawing(ScreenOutput())
DrawText(100,100,"Initializing",$ffff,0)
StopDrawing()
FlipBuffers()
; Irgendein Bild das wir verwenden, Bilder die an den Rändern ineinander
; übergehen machen sich gut. Hier ein (nicht ganz langweiliges) Schachbrett
ReceiveHTTPFile("https://www.filterforge.com/filters/2031.jpg",#targetfile)
LoadImage(1,#targetfile)
ResizeImage(1,512,512)
Dim Color.l(512,512)
; Wir lesen das Bild in ein Array, damit das Programm nicht endlos langsam ist
StartDrawing(ImageOutput(1))
For y=0 To 511
For x=0 To 511
Color(x,y)=Point(x,y)
Next
Next
StopDrawing()
StartDrawing(ScreenOutput())
Box(0,0,1024,768)
StopDrawing()
FlipBuffers()
Repeat
FlipBuffers()
ExamineKeyboard()
r.d+0.005
StartDrawing(ScreenOutput())
For y=0 To #yres-1
For x=0 To #xres-1
; Mit leichter Modifikation aus dem zweiten Artikel übernommen
; Achtung, du fütterst Cos und Sin in Programmiersprachen mit Radians Werten
; Also 0 bis 2*#PI , die 360° entsprechen. D.h. deine Werte dürfen sich nicht schnell ändern
u = x*Cos(2*r)*Sin(y/100)-y*Sin(2*r)
v = y*Cos(2*r) + x*Sin(r*1.9)
; Hier kann viel an Geschwindigkeit gewonnen werden, sieh dir die mal Drawingbuffer Befehle an
; Und eine Look Up Table holt auch nochmal einiges raus.
Plot(x,y,Color(u&511,v&511))
Next
Next
StopDrawing()
Until KeyboardPushed(#PB_Key_Escape)
DeleteFile(#targetfile)
Re: 2D Plane Deformation ?
Vielen Dank für die schnelle und ausführliche Hilfe, es lebt!
Ich habe mir den Code mal auf ein Canvasgadget umgeschrieben und das Image ist local hinterlegt (das dem 'ReceiveHTTPFile' will irgendwie nicht aber ist auch nicht so wichtig). Weiterhin habe ich den Echtzeit-Loop durch 2 LUT's ersetzt die beim Programmstart gefuellt werden, im EventLoop wird nur noch die Texture verschoben... soweit so gut. Ich will beim Start einfach nur die wichtigsten LUTs zB fuer eine Lupe erzeugen und dann ueber eine Texture legen.
Jetzt wollte ich erstmal die Formeln abbilden wo das Ergebnis bekannt ist aber das klappt irgendwie nicht.
u = x * cos(r * 2) - (y * sin(r * 2)) // 256
v = y * cos(r * 2) + (x * sin(r * 2)) // 256
Ich habe mir den Code mal auf ein Canvasgadget umgeschrieben und das Image ist local hinterlegt (das dem 'ReceiveHTTPFile' will irgendwie nicht aber ist auch nicht so wichtig). Weiterhin habe ich den Echtzeit-Loop durch 2 LUT's ersetzt die beim Programmstart gefuellt werden, im EventLoop wird nur noch die Texture verschoben... soweit so gut. Ich will beim Start einfach nur die wichtigsten LUTs zB fuer eine Lupe erzeugen und dann ueber eine Texture legen.
Jetzt wollte ich erstmal die Formeln abbilden wo das Ergebnis bekannt ist aber das klappt irgendwie nicht.
u = x * cos(r * 2) - (y * sin(r * 2)) // 256
v = y * cos(r * 2) + (x * sin(r * 2)) // 256
Code: Alles auswählen
UseJPEGImageDecoder()
LoadImage(1,"2031.jpg")
ResizeImage(1,512,512)
Dim Color.l(512,512)
StartDrawing(ImageOutput(1))
For y=0 To 511
For x=0 To 511
Color(x,y)=Point(x,y)
Next
Next
StopDrawing()
FreeImage(1)
Dim LUTX.w(640,480)
Dim LUTY.w(640,480)
;---------------------------------
;LUT's fuellen
;---------------------------------
For y = 0 To 480-1
For x = 0 To 640-1
;??????????????????????????
r.f = 1
LUTX(x,y) = x*Cos(2*r)*Sin(y/100)-y*Sin(2*r)
LUTY(x,y) = y*Cos(2*r) + x*Sin(r*1.9)
Next
Next
OpenWindow(0, 0, 0, 640, 480, "PlaneDeform", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 640, 480)
Repeat
Event = WaitWindowEvent(1000/10)
;---------------------------------
; Texture verschieben
;---------------------------------
addx + 1
addy + 1
;---------------------------------
; u/v aus LUT's holen und zeichnen
;---------------------------------
StartDrawing(CanvasOutput(0))
For y=0 To 480-1
For x=0 To 640-1
u = LUTX(x,y)
v = LUTY(x,y)
Plot(x,y,Color((u+addx)&511,(v+addy)&511))
Next
Next
StopDrawing()
Until Event = #PB_Event_CloseWindow
Zuletzt geändert von blastar am 27.01.2016 02:16, insgesamt 1-mal geändert.
Re: 2D Plane Deformation ?
Das sieht schon super aus, und viel flotter
Wegen dem ReceiveHttpFile solltest du vielleicht dein PureBasic updaten.
Sonst hat der Taschenrechner wohl ein seltsames Koordinatensystem hat bei dem 0 in der Mitte des Bildschirms liegt.
Die Skalierung ist auch etwas anders, daher das /400 beim Radius.
Ich hab das unten angepasst. Die auskommentierten Zeilen sind das Beispiel über dem von dir gewählten. Viel Spaß
Wegen dem ReceiveHttpFile solltest du vielleicht dein PureBasic updaten.
Dir hat die dynamische Berechnung von r gefehlt.- Hinzugefügt: HTTPS und einfach Auth. Unterstützung für ReceiveHTTPFile() und GetHTTPHeaders()
Sonst hat der Taschenrechner wohl ein seltsames Koordinatensystem hat bei dem 0 in der Mitte des Bildschirms liegt.
Die Skalierung ist auch etwas anders, daher das /400 beim Radius.
Ich hab das unten angepasst. Die auskommentierten Zeilen sind das Beispiel über dem von dir gewählten. Viel Spaß
Code: Alles auswählen
;---------------------------------
;LUT's fuellen
;---------------------------------
For y = 0 To 480-1
For x = 0 To 640-1
cx.d=(x-320)
cy.d=(y-240)
r.d = Sqr(cx*cx+ cy*cy)/400
a.d=ATan2(cx,cy)
LUTX(x,y) =cx* Cos(r * 2) - (cy * Sin(r * 2))
LUTY(x,y)=cy * Cos(r * 2) + (cx * Sin(r * 2))
; LUTX(x,y) =cx *80 / Abs(cy+0.001);
; LUTY(x,y) =512 / Abs(cy+0.001)*10
Next
Next
Re: 2D Plane Deformation ?
Daaanke, funktioniert bestens!
Aktuell nutze ich 5.31 da ich einige größere Projekte damit habe und bei 5.4x auf einige Problemchen gestoßen bin. Habe zwar parallel auch immer die aktuellste Version installiert (sowie auch 4.61) aber nutze aus Gewohnheit fast immer nur 5.31.
Danke!
Aktuell nutze ich 5.31 da ich einige größere Projekte damit habe und bei 5.4x auf einige Problemchen gestoßen bin. Habe zwar parallel auch immer die aktuellste Version installiert (sowie auch 4.61) aber nutze aus Gewohnheit fast immer nur 5.31.
Danke!