Netzwerkstream zerlegen - wie?
-
Hallo!
Gegeben sein eine Netzwerk-Kamera, die einen jpeg-Bild zurück gibt.
Das geht wunderbar z.B. hiermit:
TMemoryStream *MyStream = new TMemoryStream(); IdHTTP1->Get("http://cam/cgi-bin/nph-image",MyStream); MyStream->SaveToFile("bla.jpg"); MyStream->Position = 0; TJPEGImage *pJPG = new TJPEGImage(); if (MyStream) { pJPG->LoadFromStream(MyStream); Image1->Picture->Assign(pJPG); } delete pJPG; delete MyStream;Sie kann aber auch ein MJPEG-Stream liefern (das wäre dann /cgi-bin/nph-video).
Wie kann ich jetzt diesen Stream zerpflücken, damich ich bei "Vollständigkeit eines Bildes" mein TImage aktualisieren kann?
-
Mit der Image-Komponente kann man nur ein Bild darstellen, keine Sequenz von Bildern (Video).
Dafür bräuchtest du eine externe Komponente.
Schau dich mal auf http://mjpeg.sourceforge.net/ um, ob dort ein Tool angeboten wird, daß dir aus dem MJPEG-Stream eine Sequenz von JPEGs erzeugt.
-
Es ist klar, daß TImage keine Videos anzeigen kann. Ich wollte daher den Stream zerlegen und jedes mal, wenn ein Bild komplett da ist, dieses in das TImage kopieren.
-
Hallo
Dnn must du dir anschauen für das MJPEG-Format binär aufgebaut ist.
bis bald
akari
-
Ich habe das mal mit Wireshark mitgeschnibbelt:
HTTP/1.0 200 OK Server: lumenera nph-cgi Cache-Control: no-cache Pragma: no-cache Content-Type: multipart/mixed; boundary="-lumenera" ---lumenera Content-type: image/jpeg Content-length: 120364 ......Exif..MM.*.................>...........G.2.........N.i.........b....Lumenera.le375c.2007:10:12 16:40:26...........0120.............|.....&..................................................G..Z..].220549.....C....................................................................C................................................................................................ .3.......A......... ...P..O.........K....a.. /.:..z.1...+.?.z..i.........9^....... .g....?...?..?.'.m..G.....%...1?..?g>.....}..exg...R...K....^............!..?.k.A...79...A...?.o.8......[.....4.....E...........?....gO./_.?..xg...Q.......5. .......................-......_.t.....c...W.................r.3.......A......... hier kommen jetzt viele binäre daten, das 120364 byte lange jpeg <.`*/...s..a.z}...EO.|W.9.~....F..o....1KV..IE/D.....6....m...\._/... ---lumenera Content-type: image/jpeg Content-length: 120198 ......Exif..MM.*.................>...........G.2.........N.i.........b....Lumenera.le375c.2007:10:12 16:40:26...........0120.............|.....&..................................................G..Z..e|353660.....C....................................................................C................................................................................................ ................................ .....................}........!1A..Qa."q.2....#B...R..$3br.. wieder viele daten x...v\..m....Yr...s.. ---lumenera Content-type: image/jpeg Content-length: 120470 ......Exif..MM.*.................>...........G.2.........N.i.........b....Lumenera.le375c.2007:10:12 16:40:26...........0120.............|.....&..................................................G..Z....501403.....C....................................................................C................................................................................................ ................................Folgendes ist mir klar: Den http-header abgreifen, warten bis "--lunemera" kommt, dann content-type und -length abgreifen und entsprechend der Längen soundsoviel Bytes lesen.
Irgendwie fehlt mir genau da der Ansatzpunkt.
-
Hat hier wirklich noch niemals jemand einen Stream dieser o.ä. Art zerlegt, der mir zumindest einen Anhaltspunkt geben könnte, wie ich da weiterkomme?
-
Im o.g Auszug wiederholt sich die Abkürzung EXIF, die jedem ersthaftem Digitalfotografen ein Begriff ist.
Diesen EXIF-Block kannst du eigentlich schon rausfiltern/minimieren, da dort für dein Vorhaben
unnötige Angaben enthalten sind.Beschäftige dich mal mit dem jpeg-Dateiformat, z.B. bei Wikipedia findest du eine gute Erklärung.
MfG
kpeter
-
Das EXIF etc. brauche ich nicht wirklich, die Lösung sieht anders aus:
Zitat 3 Beiträge weiter oben:Folgendes ist mir klar: Den http-header abgreifen, warten bis "--lunemera" kommt, dann content-type und -length abgreifen und entsprechend der Längen soundsoviel Bytes lesen.
Mir fehlt z.Zt. nur der Ansatz.

-
Sicher kennst du die Daten deiner webcam wie
Bilder/Sek. und Auflösung der gelieferten Bilder.
Ich würde so herangehen:
Mit einem Timer den Stream hacken (Bildfrequenz) und sicherstellen, dass ab Beginn --lunemera
der Datenbock als Einzelbild on-the-fly dem Ausgabe-Image zugewiesen wird.Die EXIF-Daten kann man erst mal aussen vorlassen, denke ich.
Aber sicher gibt es im Netz Lösungsansätze...
MfG
kpeter
-
Ich muß doch nur wissen, wie ich an die Zeile "Content-length:" ran komme. Dann kommt eine Leerzeile und ab dort dann x Bytes (von Content-length:) die Bilddaten.
Und dann immer das ganze wieder von vorne...
-
Hier ein Beispiel für eine USB-Webcam. Ich weiß, du hast eine Netzwerk-Cam,
aber sieh dir den Code trotzdem mal an. Basiert auf MS API und Macros.
http://www.allanpetersen.com/index.php/contents/Main/Programming.html
MfG
kpeter