Video-Frame als BMP speichern

Anfängerfragen zum Programmieren mit PureBasic.
Dare Devil
Beiträge: 237
Registriert: 17.10.2008 18:24
Kontaktdaten:

Video-Frame als BMP speichern

Beitrag von Dare Devil »

Hallo.
Der Titel sagt eigentlich alles ...
Ich moechte einzelne Frames eines Videos als BMP speichern ... Ist das moeglich? Wenn ja wie?
Bild + Bild

Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

wie zeigst du das Video denn an?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Dare Devil
Beiträge: 237
Registriert: 17.10.2008 18:24
Kontaktdaten:

Beitrag von Dare Devil »

Kaeru Gaman hat geschrieben:wie zeigst du das Video denn an?
Mit PlayMovie() zeig ich es an, falls du das meinst :?

Der User meines Programms kann dann mit einer Track-Bar die Position des Videos festlegen und bekommt dann den Frame (als Zahl) zurueckgegeben....

Jetzt soll man diesen ausgewahlten Frame als BMP speichern koennen ... ganz einfach ;)
Bild + Bild

Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Beitrag von RSBasic »

@Dare Devil
http://www.purebasic.fr/german/viewtopic.php?t=780
Du musst den Code nur noch anpassen.
Hoffe, es hilft dir weiter ;)
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Mit PlayMovie() zeig ich es an, falls du das meinst

teilweise, es wäre noch interessant zu wissen, in welchem DeviceContext du ihn anzeigst.

grundsätzlich sollte es aber (neben der im von RSBasic verlinkten Thread geschilderten Methode) möglich sein,
wenn der gewünschte Frame sowieso gerade angezeigt wird, den Inhalt des DC zu kopieren.

bei der Frameweise Ausgabe auf einem [Windowed]Screen ginge das per GrabImage oder GrabSprite.

bei Ausgabe in einem Fenster oder Gadget weiß ich jetzt auf Anhieb nicht die Vorgehensweise,
aber auch diesen Ausgabekanal kann man per "Screenshot" speichern.

das Zerpflücken des Inhalts über den Codec bräuchtest du also nicht,
wenn du nur den aktuell angezeigten Frame speichern willst,
weil die Anzeige schon die Benutzung des Codec durchführt.
das bräuchtest du nur, wenn du den kompletten Film als Einzelbilder
darstellen willst, so wie bei einer Video-Schnitt-Software.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Dare Devil
Beiträge: 237
Registriert: 17.10.2008 18:24
Kontaktdaten:

Beitrag von Dare Devil »

Kaeru Gaman hat geschrieben:bei Ausgabe in einem Fenster oder Gadget weiß ich jetzt auf Anhieb nicht die Vorgehensweise,
aber auch diesen Ausgabekanal kann man per "Screenshot" speichern.
Das wuerde mich sehr interessieren ... Kannst du mir einen Beispielcode geben, wie du solche Screenshots simulierst? Geht so ein Screenshot auch auf nur bestimmte Teile eines Fensters? btw. es ist nur ein fenster - also kein OpenScreen() und auch kein OpenWindowedScreen()... das zweitere laesst sich doch aber problemlos erstellen, falls es noetig sein sollte, oder?
Haette frueher oder spaeter dafuer sowieso ein neues Thema erstellen muessen, da ich das noch fuer andere Funktionen des Programms brauche.... da kommt mir das grad gelegen :mrgreen:



RSBasic hat geschrieben:@Dare Devil
http://www.purebasic.fr/german/viewtopic.php?t=780
Du musst den Code nur noch anpassen.
Hoffe, es hilft dir weiter :wink:
funktioniert bei mir unter 4.20 nicht :(
Bild + Bild

Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

puh..
also wie gesagt, wie genau das geht ist mir jetzt nicht bekannt, aber dass es geht weiß ich.
es gibt eine API-Funktion, die verwendet werden kann, um "screenshots" von Fenstern oder Fensterelementen zu erstellen.

musst du halt mal im Forum suchen, nehm ich dir jetzt nicht ab,
erstrecht nicht zur PrimeTime, ich mach jetz nämlich die Glotze an... :mrgreen:

aber meine Frage hast du immer noch nicht beantwortet, auf welchen DC du denn dein PlayMovie gerichtet hast.

einfach nur auf den Fensterhintergrund, oder auf ein Image?
letzteres halte ich mal für wahrscheinlicher, da du ja anscheinend noch andere elemente im Fenster hast.
schon mal probiert, einfach SaveImage auf das AusgabeImage anzuwenden?


zum zweiten teil...
eine ausgabe auf einen [windowed]screen ist auch relativ unkompliziert,
nur dass du dort eben frameweise renderst und selber die buffer flipst.
da musst du dann auch selber fürs timing sorgen.

ob das wirklich ein vorteil ist, wenn du das mit dem "screenshot ausm DC" auch so hinbekämst, ist noch fraglich.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Dare Devil
Beiträge: 237
Registriert: 17.10.2008 18:24
Kontaktdaten:

Beitrag von Dare Devil »

Kaeru Gaman hat geschrieben:puh..
also wie gesagt, wie genau das geht ist mir jetzt nicht bekannt, aber dass es geht weiß ich.
es gibt eine API-Funktion, die verwendet werden kann, um "screenshots" von Fenstern oder Fensterelementen zu erstellen.

musst du halt mal im Forum suchen, nehm ich dir jetzt nicht ab,
erstrecht nicht zur PrimeTime, ich mach jetz nämlich die Glotze an... :mrgreen:

aber meine Frage hast du immer noch nicht beantwortet, auf welchen DC du denn dein PlayMovie gerichtet hast.

einfach nur auf den Fensterhintergrund, oder auf ein Image?
letzteres halte ich mal für wahrscheinlicher, da du ja anscheinend noch andere elemente im Fenster hast.
schon mal probiert, einfach SaveImage auf das AusgabeImage anzuwenden?


zum zweiten teil...
eine ausgabe auf einen [windowed]screen ist auch relativ unkompliziert,
nur dass du dort eben frameweise renderst und selber die buffer flipst.
da musst du dann auch selber fürs timing sorgen.

ob das wirklich ein vorteil ist, wenn du das mit dem "screenshot ausm DC" auch so hinbekämst, ist noch fraglich.
Weiss jetzt nicht sicher wie du das meinst (eigtl. weiss ich nur nicht, was DeviceContext ist :mrgreen: ist mir einwenig peinlich - bin halt ein noob :( ), aber ich spiele das Video folgendermassen in meinem Fenster ab:

Code: Alles auswählen

;Hier lade ich die Datei
moviep = LoadMovie(#PB_Any, datei$)

;Hier stelle ich die Groesse ein:
ResizeMovie(moviep, 140, 50, 150, 100)

;Und hier spiele ich sie ab
PlayMovie(moviep, WindowID(#Fenster))
ist also nicht auf nem image oder wie auch immer - glaub ich zumindest :mrgreen:


Nur eines ist seltsam... Wenn ich (oder der User) das Video pausiere (mit PauseMovie()), mit einem ButtonGadget - und anschliessend das Fenster verschiebe, dann bewegt sich das Frame wo das Video angehalten wurde nicht mit dem Fenster mit, was etwas aergerlich ist ...




Zum Screenshot-Thema:
Habe jetzt nach laengerem Suchen etwas gefunden:

Code: Alles auswählen

Procedure MakeWinScreenshot(ImageNr,hWnd,Width,Height) 
   hImage = CreateImage(ImageNr,Width,Height) 
   hDC = StartDrawing(ImageOutput(ImageNr)) 
   Debug hDC 
      BitBlt_(hdc,0,0,Width,Height,GetDC_(hWnd),0,0,#SRCCOPY) 
   StopDrawing() 
   ProcedureReturn hImage 
EndProcedure 

OpenWindow(1,0,0,600,300,"",#PB_Window_SystemMenu|#PB_Window_Invisible|#PB_Window_ScreenCentered) 
  CreateGadgetList(WindowID(1)) 

  hShotWindow = FindWindow_(0,"PureBasic")   ; enter the right name here! 
  If hShotWindow 
    hWinBmp  = MakeWinScreenshot(1,hShotWindow,600,300) 
    ImageGadget(1,0,0,600,300,hWinBmp) 
    
  EndIf 

HideWindow(1,0) 

Repeat 
  Select WaitWindowEvent() 
    Case #PB_Event_CloseWindow : End 
  EndSelect 
ForEver
Anscheinend erstellt die API-Funktion BitBlt_() den Screenshot zu machen ... jetzt hab ich etwas gegooglet, um herauszufinden wie ich diese Funktion fuer meine Zwecke nutzen kann - bin aber immer noch nicht schlauer ... wie mache ich jetzt einen Screenshot NUR vom angezeigten Frame?
Bild + Bild

Bild
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> PlayMovie(moviep, WindowID(#Fenster))

also spielst du direkt im fenster ab.

> dann bewegt sich das Frame wo das Video angehalten wurde nicht mit dem Fenster mit, was etwas aergerlich ist ...

oh.. dann könnte es sogar sein, dass play movie garnicht ins fenster selber zeichnet, sondern nur auf den Desktop an der angegebenen stelle.
wie es intern wirklich funktioniert, weiß ich garnicht.

> Habe jetzt nach laengerem Suchen etwas gefunden
> Anscheinend erstellt die API-Funktion BitBlt_() den Screenshot

das sieht doch schon mal gut aus.
verwende doch mal diese Proc, als hWnd kannst du auch WindowID(#myMovieWindow) einsetzen.

mal sehen ob das schon funktioniert. wenn PlayMovie wirklich ins Fenster rendert,
(also das Fenster / der Fensterhintergrund der Device Context für die Ausgabe des Movies ist)
sollte das funktionieren und das zurückgegebene Image den Shot vom Movie Frame beinhalten.

wenn es nicht funktioniert, läuft das irgendwie anders.
dann wäre der nächste schritt, es stattdessen mal in ein Gadget zu rendern,
und wenn das immer nochnicht läuft, dann mal in ein Image.


kann natürlich sein, dass jemand anderes konkretere vorschläge hat.
wie gesagt, Movies sind nicht meine profession.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Dare Devil
Beiträge: 237
Registriert: 17.10.2008 18:24
Kontaktdaten:

Beitrag von Dare Devil »

Hab es jetzt nach langem rumprobieren endlich geschafft

Jetzt kann ich screenshots machen, wo, was und wie gross ich will :)

Allerdings habe ich ein weiteres Problem. Wenn ich ein Screenshot vom Videoframe machen will ist das Ergebnis ein schwarzer Bildschirm...

Und das ist kein Programmierproblem ... wenn ich manuell mit der Print-Taste einen Screenshot mache kommt ebenfalls nur schwarz raus an der Stelle wo das Videoframe stand


Also kann ich die Screenshot-Methode schonmal vergessen .... (zumindest fuer mein Video-Problem)
Bild + Bild

Bild
Antworten