Capture a movie frame
Posted: Mon Feb 02, 2004 2:07 am
				
				Hello,
I wrote a little routine today, to capture the current frame of a movie
to a pb image. I noticed, that this has been asked here before, without
a solution, so here it is:
Have fun...
Timo
			I wrote a little routine today, to capture the current frame of a movie
to a pb image. I noticed, that this has been asked here before, without
a solution, so here it is:
Code: Select all
; ---------------------------------------------------------------------
;
; CaptureFrame(#Movie, #Image, #Memory)
;
; Copies the current frame of the #Movie to the #Image.
; The movie must pe paused when calling this, otherwise it will fail.
; The #Image should be the same size as the movie (MovieWidth(), MovieHeight())
; You must provide an unused memory bank number for temporary storage.
;
; ---------------------------------------------------------------------
Structure PB_StructureMovie
  Movie.l          ; IGraphBuilder DirectShow pointer
  MediaControl.l   ; IMediaControl DirectShow pointer
  MediaEvent.l     ; IMediaEventEx DirectShow pointer
  Window.l         ; IVideoWindow DirectShow pointer
  Audio.l          ; IBasicAudio DirectShow pointer
  Video.l          ; IBasicVideo DirectShow pointer
  MediaSeeking.l   ; IMediaSeeking DirectShow pointer
  State.l          ; State of the movie
EndStructure
Procedure.l CaptureFrame(MovieNumber, ImageNumber, MemoryBank)
  Protected *Movie.PB_StructureMovie, *Video.IBasicVideo, *Window.IVideoWindow
  Protected *ImageData.BITMAPINFOHEADER, DataSize, Parent, Result
  
  !extrn _PB_Movie_ObjectsArea
  !mov eax, [_PB_Movie_ObjectsArea]
  !mov [esp+12], eax
  
  *Movie  + MovieNumber * SizeOf(PB_StructureMovie)
  *Window = *Movie\Window
  *Video  = *Movie\Video
  
  Result  = 0  
  
  If *Video\GetCurrentImage(@DataSize, 0) = #S_OK
  
    *ImageData = AllocateMemory(MemoryBank, DataSize)
    If *ImageData
    
      If *Video\GetCurrentImage(@DataSize, *ImageData) = #S_OK
            
        Result = SetDIBits_(0, UseImage(ImageNumber), 0, *ImageData\biHeight, *ImageData+*ImageData\biSize, *ImageData, #DIB_RGB_COLORS)
      
      EndIf
    
      FreeMemory(MemoryBank)
    EndIf
  
  EndIf    
  
  *Window\get_Owner(@Parent)  
  RedrawWindow_(Parent,0,0,#RDW_INVALIDATE)
    
  ProcedureReturn Result
EndProcedure
; ---------------------------------------------------------------------
; Code example:
; ---------------------------------------------------------------------
#Movie = 0
#Image = 0
#Memory = 0
#Window = 0
#Gadget_Capture = 0
#Gadget_Image  = 1
If InitMovie()
  FileName$ = OpenFileRequester("Choose Movie","","Movie Files|*.mpg;*.avi;*.mpeg|All Files|*.*", 0)
  
  If LoadMovie(#Movie, FileName$)
  
    Width = MovieWidth()
    Height = MovieHeight()
  
    CreateImage(#Image, Width , Height)
    If OpenWindow(#Window, 0, 0, Width , Height*2 + 35, #PB_Window_SystemMenu|#PB_Window_Screencentered|#PB_Window_Invisible, "Frame Capture")
    
      If CreateGadgetList(WindowID())
      
        ButtonGadget(#Gadget_Capture, (Width -100)/2, Height+5, 100, 25, "Capture Frame")
        ImageGadget(#Gadget_Image, 0, Height+35, Width, Height, UseImage(#Image))
        
        PlayMovie(#Movie, WindowID())
        
        HideWindow(#Window, 0)
        
        Repeat
          Event = WindowEvent()
          
          If Event = #PB_EventGadget And EventGadgetID() = #Gadget_Capture
          
            PauseMovie()
            
            CaptureFrame(#Movie, #Image, #Memory)
            SetGadgetState(#Gadget_Image, UseImage(#Image))                        
            
            ResumeMovie()         
            
          
          EndIf
          
          If Event = 0
            Delay(1)
          EndIf
          
        Until Event = #PB_EventCloseWindow
        
      EndIf        
      
    EndIf        
    
  EndIf
  
EndIf
EndTimo

