Page 1 of 1

Simulating damaged TV

Posted: Thu Feb 12, 2009 5:22 am
by Seymour Clufley
This is a BorisFX filter:
Image

A bigger version can be seen here.

I'd like to do something like it in PB. Ideally, a sequence of 20 or 30 "frames" in which the effect mutates realistically. (Each frame to be saved as a bitmap.)

The scanlines aren't the problem as they can simply be overlaid, but what about the sine wave distortion? Does anyone have any tricks as to how that could be achieved?

Re: Simulating damaged TV

Posted: Thu Feb 12, 2009 11:24 am
by PB
There was something like this here before, or maybe just a white noise effect.

Posted: Thu Feb 12, 2009 1:37 pm
by DarkLord
I don't really know enough about PureBasic yet, but I'm sure there is a way to manipulate the image using memory blocks, I might look further into this problem unless someone knows how to code this.

Posted: Thu Feb 12, 2009 1:59 pm
by Anonymous
You can use Shader on sprite3D no ?

Posted: Thu Feb 12, 2009 3:01 pm
by Kaeru Gaman
the basic question is, what output you want this effect for.
manipulating an image, or realtime on a screen?
for the latter, you could clip a sprite in single lines and alter the x-coordinate.

Posted: Thu Feb 12, 2009 3:17 pm
by Seymour Clufley
It's for manipulating an image.

Posted: Thu Feb 12, 2009 3:44 pm
by Kaeru Gaman
the maths would be the same:
take a line from the source image and put it to the destination image, alter the left start x-coord with a multiple sinus.

Posted: Thu Feb 12, 2009 7:53 pm
by Seymour Clufley
Kaeru Gaman wrote:alter the left start x-coord with a multiple sinus.
I'm sorry, I don't know what you mean by multiple sinus. Can you give an example, like:

Code: Select all

StartX = 

Posted: Thu Feb 12, 2009 8:28 pm
by Comtois
not exactly what you are looking for, but may be this can help ?

Code: Select all

;Comtois 09/04/05

;{- Initialisation
#ScreenWidth  = 640 : #ScreenHeight = 480 : #ScreenDepth  = 32
If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 ) : End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "Effets" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 ) : End
EndIf

;replace this by a nice image
CreateSprite(1,640,480)
StartDrawing(SpriteOutput(1))
For i=0 To 20
  Circle(Random(640), Random(480), Random(100)+40,RGB(Random(255),Random(255),Random(255)))
  Box(Random(640), Random(480), Random(150)+40,Random(150)+40,RGB(Random(255),Random(255),Random(255)))  
Next i  
StopDrawing()

CreateSprite(0, SpriteWidth(1), SpriteHeight(1))
 
Niveau.f = 100
Hauteur = SpriteHeight(1) - 1

Repeat
 
  ClearScreen(0)
 
  ExamineKeyboard()
 
 
  UseBuffer(0)
 
  For i = 0 To Hauteur
    ClipSprite(1, 0, i,  SpriteWidth(1), 1)
    DisplaySprite(1, Random(Niveau), i )
  Next i
 
  UseBuffer(-1)
 
  Niveau = Niveau * 0.99
 
  DisplaySprite(0, 0, 0) 
 
  FlipBuffers()
 
Until KeyboardPushed(#PB_Key_Escape)

Code: Select all

;Comtois 09/04/05

;{- Initialisation
#ScreenWidth  = 800 : #ScreenHeight = 600 : #ScreenDepth  = 32
If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 ) : End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "Effets" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 ) : End
EndIf

;replace this by a nice image
CreateSprite(0,640,480)
StartDrawing(SpriteOutput(0))
For i=0 To 20
  Circle(Random(640), Random(480), Random(100)+40,RGB(Random(255),Random(255),Random(255)))
  Box(Random(640), Random(480), Random(150)+40,Random(150)+40,RGB(Random(255),Random(255),Random(255)))  
Next i  
StopDrawing()

HauteurSprite = SpriteHeight(0)
Angle   = 0
Pas     = 1
Vitesse = 2
Amplitude = 25

CentreX = (#ScreenWidth  - SpriteWidth(0))  / 2
CentreY = (#ScreenHeight - SpriteHeight(0)) / 2

Repeat
  ClearScreen(0)
  StartDrawing(ScreenOutput())
  DrawingMode(1)
  FrontColor(RGB(255,255,255))
  DrawText(0,0,"Amusez vous avec les touches up/down, Left/Right et PageUp/PageDown")
  StopDrawing()
  PositionY = 0
  For i = 1 To HauteurSprite
    ClipSprite(0, 0, PositionY, SpriteWidth(0), 1)
    DisplaySprite(0, CentreX + (Sin((Angle + i * Pas) * 0.0174533 ) * Amplitude) , CentreY + i)
    PositionY + 1
  Next i
 
  Angle + Vitesse
 
  ExamineKeyboard()
 
  If KeyboardPushed(#PB_Key_PageUp)
   
    Amplitude + 1
    If Amplitude > CentreX : Amplitude = CentreX : EndIf
   
  ElseIf KeyboardPushed(#PB_Key_PageDown)
   
    Amplitude - 1
    If Amplitude < 0  : Amplitude = 0 : EndIf
   
  EndIf
 
  If KeyboardReleased(#PB_Key_Up)
 
    Vitesse + 1
    If Vitesse > 30 : Vitesse = 30 : EndIf
   
  ElseIf KeyboardReleased(#PB_Key_Down)
   
    Vitesse - 1
    If Vitesse < 0  : Vitesse = 0 : EndIf
   
  EndIf
 
  If KeyboardReleased(#PB_Key_Left)
   
    Pas + 1
    If Pas > 20 : Pas = 20 : EndIf
   
  ElseIf KeyboardReleased(#PB_Key_Right)
   
    Pas - 1
    If Pas < 0 : Pas = 0 : EndIf
   
  EndIf
 
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)              

Code: Select all

;Comtois 09/04/05

;{- Initialisation
#ScreenWidth  = 640 : #ScreenHeight = 480 : #ScreenDepth  = 32
If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 ) : End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "Effets" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 ) : End
EndIf

;replace this by a nice image
CreateSprite(1,640,480)
StartDrawing(SpriteOutput(1))
For i=0 To 20
  Circle(Random(640), Random(480), Random(100)+40,RGB(Random(255),Random(255),Random(255)))
  Box(Random(640), Random(480), Random(150)+40,Random(150)+40,RGB(Random(255),Random(255),Random(255)))  
Next i  
StopDrawing()

CreateSprite(0, SpriteWidth(1), SpriteHeight(1))
 
Niveau = 200 ; Modifiez cette valeur
Hauteur = SpriteHeight(1) - 1

Repeat
 
  ClearScreen(0)
 
  UseBuffer(0)
 
  For i = 0 To Hauteur
    ClipSprite(1, 0, i,  SpriteWidth(1), 1)
    DisplaySprite(1, Random(Niveau), i )
  Next i
 
  UseBuffer(-1)
 
  Niveau - 1
 
  DisplaySprite(0, 0, 0) 

  FlipBuffers()
 
Until Niveau < 0

Posted: Thu Feb 12, 2009 8:38 pm
by Kaeru Gaman
this is a regular double sine

Code: Select all

Phase1.d = 30.00   ; big   Phaselength = 30  * 2pi pixel
Phase2.d =  2.50   ; small Phaselength = 2.5 * 2pi pixel

Ampli1.d = 14.00   ; big   Amplitude 14 pixel
Ampli2.d =  6.00   ; small Amplitude  6 pixel

CreateImage( 0, 800, 50 )

; draw the sine wave horizontal
; named it StartX tho it's an Y

StartDrawing( ImageOutput( 0 ) )
  For n=0 To 799
    StartX.d = 25
    StartX + Ampli1 * Sin( n / Phase1 )   ; Adding  big  Sine
    StartX + Ampli2 * Sin( n / Phase2 )   ; Adding small Sine
    Plot( n, StartX, $40FFC0 )
  Next
StopDrawing()

OpenWindow( 0, #PB_Ignore,0, 800,50, "Sine Demo" )
  ImageGadget( 0, 0,0,800,50, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
to achieve irreglularity, perhaps add some dynamic randomness on aplitude and phase...

Code: Select all

Phase1.d = 30.00   ; big   Phaselength = 30  * 2pi pixel
Phase2.d =  2.50   ; small Phaselength = 2.5 * 2pi pixel

Ampli1.d = 14.00   ; big   Amplitude 14 pixel
Ampli2.d =  6.00   ; small Amplitude  6 pixel

#Imagewidth = 800
#ImageHeight = 100

CreateImage( 0, #Imagewidth, #ImageHeight )

; draw the sine wave horizontal
; named it StartX tho it's an Y

StartDrawing( ImageOutput( 0 ) )
  For n=0 To 799
    StartX.d = #ImageHeight / 2
    RandomPhase1.d = (Random(8)-4)/2
      Phase1 + RandomPhase1
    RandomAmpli1.d = (Random(8)-4)/2
      Ampli1 + RandomAmpli1
    RandomPhase2.d = (Random(8)-4)/2
      Phase2 + RandomPhase2
    RandomAmpli2.d = (Random(8)-4)/2
      Ampli2 + RandomAmpli2

Phase1.d = 30.00   ; big   Phaselength = 30  * 2pi pixel

Ampli1.d = 14.00   ; big   Amplitude 14 pixel
Ampli2.d =  6.00   ; small Amplitude  6 pixel
    
    StartX + Ampli1 * Sin( n / Phase1 )   ; Adding  big  Sine
    StartX + Ampli2 * Sin( n / Phase2 )   ; Adding small Sine
    If StartX >= 0 And StartX < #ImageHeight
      Plot( n, StartX, $40FFC0 )
    EndIf
  Next
StopDrawing()

OpenWindow( 0, #PB_Ignore,0, #Imagewidth, #ImageHeight, "Sine Demo" )
  ImageGadget( 0, 0,0,#Imagewidth, #ImageHeight, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Posted: Fri Feb 13, 2009 3:26 pm
by Seymour Clufley
Thanks, Kaeru. That's great. :)

Posted: Fri Feb 13, 2009 6:29 pm
by Kaeru Gaman
argh... I just see, I got crap left in the second code...
you have to cut the three lines out where the start values are reset.
(copiet them there to cut the names out)

this is what I meant:

Code: Select all

Phase1.d = 30.00   ; big   Phaselength = 30  * 2pi pixel
Phase2.d =  2.50   ; small Phaselength = 2.5 * 2pi pixel

Ampli1.d = 14.00   ; big   Amplitude 14 pixel
Ampli2.d =  6.00   ; small Amplitude  6 pixel

#Imagewidth = 800
#ImageHeight = 100

CreateImage( 0, #Imagewidth, #ImageHeight )

; draw the sine wave horizontal
; named it StartX tho it's an Y

StartDrawing( ImageOutput( 0 ) )
  For n=0 To 799
    StartX.d = #ImageHeight / 2
    RandomPhase1.d = (Random(8)-4)/2
      Phase1 + RandomPhase1
    RandomAmpli1.d = (Random(8)-4)/2
      Ampli1 + RandomAmpli1
    RandomPhase2.d = (Random(8)-4)/2
      Phase2 + RandomPhase2
    RandomAmpli2.d = (Random(8)-4)/2
      Ampli2 + RandomAmpli2
    
    StartX + Ampli1 * Sin( n / Phase1 )   ; Adding  big  Sine
    StartX + Ampli2 * Sin( n / Phase2 )   ; Adding small Sine
    If StartX >= 0 And StartX < #ImageHeight
      Plot( n, StartX, $40FFC0 )
    EndIf
  Next
StopDrawing()

OpenWindow( 0, #PB_Ignore,0, #Imagewidth, #ImageHeight, "Sine Demo" )
  ImageGadget( 0, 0,0,#Imagewidth, #ImageHeight, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
I think the randomness should be worked over, it spreads too wide on later curve in too many cases...