Benutzer mit den meisten Antworten
Bild einer Webcam drehen

Frage
-
Hallo,
ich habe das Bild einer Webcam, das ich je nach Bild drehen muss. Das habe ich mit
Me.picCapture.Image.RotateFlip(RotateFlipType.Rotate90FlipXY)
versucht.
Hier meckert das Programm beim Ausführen an, dass ich eine Objektinstanz mit dem Schlüsselwort "new" erzeugen soll.
Ich habe dann folgendes versucht:Dim picCapture As New Image bekomme dann allerdings die Mitteilung:
"New" darf nicht für eine Klasse verwendet werden, die als "MustInherit" deklariert ist.
Was mache ich denn falsch oder wie geht es richtig?
Liebe Grüße Stefan
Antworten
-
Hallo Stefan,
Wenn ich das richtig sehe ist es nicht die Image Eigenschaft die benötigt wird, sondern das Fensterhandle, damit Du Dein Bild anzeigen kannst. Isgendwo im anderen Thread stand nämlich:
hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 1280, 860, picCapture.Handle.ToInt32, 0)
Da steht definitiv picCapture.Handle, damit ist die Image-Eigenschaft der PictureBox außen vor. Du könntest also jedes ander Steuerelement benutzen, welches ein Window hat. Ich habe mir das nicht näher angeschaut, aber ich befürchte das mit der Funktion nicht möglich ist, das Image in irgendeiner Art und Weise zu drehen. Wenn Du mit Bildsequenzen leben kannst, bleibt Dir die Möglichkeit das Image temporär zu speichern, zu bearbeitet und dann der Image-Egenschaft zu zuweisen. Das ganze könntest Du in einem Timer-Event machen, doch erhoffe Dir kein flackerfreies Bild. Das zu müsstest Du mindest 24 Bilder pro Sekunde darstellen. Wenn ich das richtig sehen sind der 5. und 6. Parameter die Größe des Bildes. Das ist viel zuviel um ein flackfreies Bild mittels der PictureBox zu erhalten. Ein eigenes Control könnte vielleicht helfen aber immer noch nicht ausreichen. Was vielleicht wirklich den Erfolg bringt ist DirectX(DirectShow) zu benutzen. Ich weiß dass das geht, ich weiß allerdings auch dass das kein "Dreizeiler" wird. Wie das genau geht musst Du dem SDK zu DirectX entnehmen. Hier schon mal ein vorab Link:
http://msdn.microsoft.com/en-us/library/dd407331(v=VS.85).aspx
Gruß Scotty
- Als Antwort markiert Giftzwockel Freitag, 14. Mai 2010 09:47
Alle Antworten
-
Hallo Stefan,
Wenn ich das richtig sehe ist es nicht die Image Eigenschaft die benötigt wird, sondern das Fensterhandle, damit Du Dein Bild anzeigen kannst. Isgendwo im anderen Thread stand nämlich:
hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 1280, 860, picCapture.Handle.ToInt32, 0)
Da steht definitiv picCapture.Handle, damit ist die Image-Eigenschaft der PictureBox außen vor. Du könntest also jedes ander Steuerelement benutzen, welches ein Window hat. Ich habe mir das nicht näher angeschaut, aber ich befürchte das mit der Funktion nicht möglich ist, das Image in irgendeiner Art und Weise zu drehen. Wenn Du mit Bildsequenzen leben kannst, bleibt Dir die Möglichkeit das Image temporär zu speichern, zu bearbeitet und dann der Image-Egenschaft zu zuweisen. Das ganze könntest Du in einem Timer-Event machen, doch erhoffe Dir kein flackerfreies Bild. Das zu müsstest Du mindest 24 Bilder pro Sekunde darstellen. Wenn ich das richtig sehen sind der 5. und 6. Parameter die Größe des Bildes. Das ist viel zuviel um ein flackfreies Bild mittels der PictureBox zu erhalten. Ein eigenes Control könnte vielleicht helfen aber immer noch nicht ausreichen. Was vielleicht wirklich den Erfolg bringt ist DirectX(DirectShow) zu benutzen. Ich weiß dass das geht, ich weiß allerdings auch dass das kein "Dreizeiler" wird. Wie das genau geht musst Du dem SDK zu DirectX entnehmen. Hier schon mal ein vorab Link:
http://msdn.microsoft.com/en-us/library/dd407331(v=VS.85).aspx
Gruß Scotty
- Als Antwort markiert Giftzwockel Freitag, 14. Mai 2010 09:47
-
Hallo Stefan,
Möchtest Du tatsächlichen den Video-Stream oder die einzelne Bilder drehen?
http://vbcity.com/forums/t/94053.aspx
[Beispiel VB.NET Code zum drehen einer PictureBox mit dem Beliebigen Winkel]
Imports System.Drawing.Drawing2D Imports System.Math Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim bm_in As New Bitmap(picSource.Image) '// Array von Punkten, die die Bild Ecken definieren Dim wid As Single = bm_in.Width Dim hgt As Single = bm_in.Height Dim corners As Point() = { _ New Point(0, 0), _ New Point(wid, 0), _ New Point(0, hgt), _ New Point(wid, hgt)} '//Translation Dim cx As Single = wid / 2 Dim cy As Single = hgt / 2 Dim i As Long For i = 0 To 3 corners(i).X -= cx corners(i).Y -= cy Next i '//Drehen Dim theta As Single = Single.Parse("270") * PI / 180.0 '//Beliebigen Winkel eingeben Dim sin_theta As Single = Sin(theta) Dim cos_theta As Single = Cos(theta) Dim X As Single Dim Y As Single For i = 0 To 3 X = corners(i).X Y = corners(i).Y corners(i).X = X * cos_theta + Y * sin_theta corners(i).Y = -X * sin_theta + Y * cos_theta Next i '//Translate, so das X >= 0 und Y >=0 für alle Ecken Dim xmin As Single = corners(0).X Dim ymin As Single = corners(0).Y For i = 1 To 3 If xmin > corners(i).X Then xmin = corners(i).X If ymin > corners(i).Y Then ymin = corners(i).Y Next i For i = 0 To 3 corners(i).X -= xmin corners(i).Y -= ymin Next i '//Output Bitmap als Graphisches Objekt Dim bm_out As New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin)) Dim gr_out As Graphics = Graphics.FromImage(bm_out) ReDim Preserve corners(2) '//Resultat in das Output Bitmap speichern gr_out.DrawImage(bm_in, corners) '//Endresultat picDest.Image = bm_out End Sub End Class
Grüße,
Robert
-
Hallo Robert,
nun ja, so ein Stream ist eine komplexe Angelegenheit. Alleine wenn ich mir ansehe, dass ich Einfluss auf die Auflöung der Kamera, Anzahl der Bilder per Sekunde nehmen kann und das bei bewegten Bildern neu berechnet werden muss, sehe ich schon, was Karsten andeutet.
Dann habe ich eigentlich noch andere Ideen zu dem Thema gehabt. Da bin ich noch nicht weit genug und stelle das Programm lieber mal hinten an.
Euch beiden vielen Dank.
Aber auf diesem Weg mal eine ganz banale andere Frage. Ich sehe sehr oft, dass du Beiträge bzgl. der Formatierung nachbearbeitest.
Gibt es Einstellungen oder Empfehlungen die dazu führen, dass die Formatierung gleich in Ordnung ist?
Liebe Grüße Stefan -
Hallo Stefan,
Möchtest Du tatsächlichen den Video-Stream oder die einzelne Bilder drehen?
http://vbcity.com/forums/t/94053.aspx
[Beispiel VB.NET Code zum drehen einer PictureBox mit dem Beliebigen Winkel]
Imports System.Drawing.Drawing2D Imports System.Math Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim bm_in As New Bitmap(picSource.Image) '// Array von Punkten, die die Bild Ecken definieren Dim wid As Single = bm_in.Width Dim hgt As Single = bm_in.Height Dim corners As Point() = { _ New Point(0, 0), _ New Point(wid, 0), _ New Point(0, hgt), _ New Point(wid, hgt)} '//Translation Dim cx As Single = wid / 2 Dim cy As Single = hgt / 2 Dim i As Long For i = 0 To 3 corners(i).X -= cx corners(i).Y -= cy Next i '//Drehen Dim theta As Single = Single.Parse("270") * PI / 180.0 '//Beliebigen Winkel eingeben Dim sin_theta As Single = Sin(theta) Dim cos_theta As Single = Cos(theta) Dim X As Single Dim Y As Single For i = 0 To 3 X = corners(i).X Y = corners(i).Y corners(i).X = X * cos_theta + Y * sin_theta corners(i).Y = -X * sin_theta + Y * cos_theta Next i '//Translate, so das X >= 0 und Y >=0 für alle Ecken Dim xmin As Single = corners(0).X Dim ymin As Single = corners(0).Y For i = 1 To 3 If xmin > corners(i).X Then xmin = corners(i).X If ymin > corners(i).Y Then ymin = corners(i).Y Next i For i = 0 To 3 corners(i).X -= xmin corners(i).Y -= ymin Next i '//Output Bitmap als Graphisches Objekt Dim bm_out As New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin)) Dim gr_out As Graphics = Graphics.FromImage(bm_out) ReDim Preserve corners(2) '//Resultat in das Output Bitmap speichern gr_out.DrawImage(bm_in, corners) '//Endresultat picDest.Image = bm_out End Sub End Class
Grüße,
Robert
Hallo Robert,diese Source muss man nicht wirklich verstehen, oder? Ich meine wenn Du letzendlich das Array so wie so auf 3 Elemente "zurück schneidest", warum berechnest Du vorher 4 Elemente? Ganz davon abgesehen würde ich kein Array benutzen, sondern eine List(of Point). Aber abgesehen davon ergibt das ein Standbild und ich glaube nicht dass das der OP das wollte.
--
Gruß Scotty
-
Hallo Stefan,
wie ich bereits angemerkt habe, ist so etwas nicht mit einem "Dreizeiler" erledigt. Roberts Lösung geht in die Richtung, das Du mit GDI+ machen kannst. Jedoch ist GDI+ nicht hardware-beschleunigt. Dies wiederum führt automatisch bei einer hohen "Bildauflösung" zu langsamen Frame-Rates die keine flackerfreie Darstellung ermöglichen. Mit DirectX ist das möglich, da DirectX Deine Grafikkarte direkt ansteuert und den dafür ausgelegten Prozessor und Speicher bemüht. DirectX braucht auch nur ein Fensterhandle, dass kann auch ein Handle einer bspw. PictureBox sein. Doch wie ich schon sagte, das nicht eben mal so getan, da diese Technologie nicht mit Dir diskutiert, entweder es funktioniert oder nicht. Detailierte Fehlermeldungen liefert Dir DirectX, auch wenn die Managed Variante nutzt nicht. OpenGL wäre noch eine Alternative, aber frag mich nicht nach Details, ich kann zwar viel essen, aber nicht alles wissen.
--
Gruß Scotty
-
Hallo Karsten Sosna,
Deswegen habe ich am Anfang die Direkte Frage gefragt:
„Möchtest Du tatsächlichen den Video-Stream oder die einzelne Bilder drehen?“
Nachher habe ich eine Lösung, die funktioniert, für den zweiten Teil der Frage gegeben (einzelne Bilder drehen) (die man sicher wie Du sagst noch besser schreiben kann – Danke für den Hilfreichen Hinweis).
Bin später draufgekommen dass Stefan den Video-Stream meinte. Klar, wie Du sagst ist Hardware (DirectX, OpenGL) bearbeiten besser als Software (GDI+).
@Stefan: Ich bearbeite die Formatierung weil die Forum Plattform zeigt manchmal sehr schlecht (klein geschrieben, verschiedene Fonts, etc.) den Beitrag an. Und wenn da noch Code inzwischen ist sieht das sehr schlecht aus und die Benutzer (jetzige, zukünftige) können das sehr schwer verstehen. Wenn ich ein Beitrag poste mache ich folgendes: schreibe es zuerst in Word, immer mit Verdana 8 und nachher Copy&Paste in den Forum Editor. Code immer durch den Knopf „Codeblock einfügen“.
Grüße,
Robert