Hallo,
ich filme mit einer Webcam ein iPad. Der WebcamStream ist in einer pictureBox eingebunden.
Ich möchte, dass der Anwender zur Laufzeit die Größe der PictureBox ändern/verkleinern kann.
So, dass nacher auf dem Webcamstream nur noch das iPad zusehen ist und kein unnötiger Hintergund.
Ich habe schon probiert, dass mit Buttons zu lösen. Leider kann ich mit den Properties Width and High die PictureBox nur von OBEN und RECHTS her verändern/verkleinern.
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Width = pictureBox1.Width - 1;
}
private void button2_Click(object sender, EventArgs e)
{
pictureBox1.Height = pictureBox1.Height - 1;
}
Gibt es auch Eigenschaften, um die PictureBOx von LINKS und OBEN zu verändern?
oder wie würde ihr das Problem lösen?
Liebe Grüße,
Elias
So soll es danach aussehen:
eig sollte die picturebox hier kleiner sein.
Aber habe geschummelt indem ich die Webcam näher rangerückt habe.
Hier soll nur klar werden, dass man versteht welcher Teil noch in der pictureBox noch zu sehen sein soll.
Hallo,
du willst also gar nicht die Größe der PictureBox verändern, sondern das enthaltene Bild zoomen, s z.B. Grafik in PictureBox vergrößern
Auf CodeProject gibt es auch eine fertige Komponente dafür: A Zoomable and Scrollable PictureBox
Beim Zoomen sehe ich aber das Problem, dass sich mein Bild:
verzerrt: meine PicBox ist momentan 640:480 groß. Das iPad hat aber ein ganz anderes Seitenverhältnis (nehmen wir mal quadratisch 400x400 an) würde ich das jetzt ranzoomen wäre mein qudratisch ipad als 640x480 Verhätnis abgebildet.
Das ist der Grund warum ich die Größe der PictureBox verändern lassen will. So kann ich immer je nachdem welches Seitenverhätnis das iPad hat durch Anpassen der Picturebox exakt dasselbe Seitenverhätnis bekommen.
Beispiel: Ist mein ipad wie oben z.B Qudratisch, könnte ich meine picture Box auch quadratisch ziehen.
Verstehst du was ich meine?
Hallo,
die Position (links, oben) läßt sich über die Eigenschaften Left und Top ändern.
Ja aber die Position hilft mir ja da reichlich wenig. Ich will die pictureBox ja nicht verschieben.
Am liebsten wären mir 4 Buttons mit denen ich die picturebox von jeweils allen Seiten verkleinern kann.
Width und Height machen das ja schon teilweise. Nur verkleinern diese eben die PictureBox nur von OBEN und von RECHTS. Jetzt bräuchte ich noch was die pictureBox von LINKS und UNTEn her verkleinert.
~~Du musst in dem Falle die Position und die Höhe/Breite ändern.
Beispiel:
Control.Left ist 0
Control.Width ist 100
Willst du Links verkleinern, setzt du Left auf 1 und Width auf 99.~~
EDIT: Wobei das eigtl. überhaupt nichts bringt, das Bild "wandert" dann mit.
Was ich mir auch noch vorstellen könnte:
Ich zeichne ein Rectangle über das iPad und die pictureBox soll sich dann auf die Größe des Rectangles einstellen.
Aber weiß nicht wie ich das umsetzen könnte.
Hallo Elias,
Wenn Du Width und Height veränderst dann verändert sich die Größe des Bitmap rechts und unten (Location 0,0 ist oben links).
Wenn Du Width und Location.X gleichzeitig ändert dann änderst sich der rechte Rand.
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
Hallo es geht ja um die pictureBox.
Habe eine pictureBox eingefügt und zwei Buttons:
private void button3_Right_Click(object sender, EventArgs e)
{
pictureBox1.Width = pictureBox1.Width - 5;
}
private void button4_Top_Click(object sender, EventArgs e)
{
pictureBox1.Height = pictureBox1.Height - 5;
}
Kannst ja mal selber ausprobieren: Picturebox, 2 Buttons und der obere Code. Es ist genau andersherum:
WIDTH wird von RECHTS kleiner.
HEIGHT wird von OBEN kleiner.
Wie soll mir da jetzt Location weiterhelfen?
Jetzt brauche ich noch 2 Buttons mit denen ich die Picturebox von LINKS und von UNTEN verkleinern kann.
Kannst du kurz mal zeigen, wie die PictureBox definiert ist? Standardmäßig verkleinert sie sich nämlich rechts und unten.
Zum eigtl. Problem:
Selbst wenn du Links und Oben (oder bei dir unten) setzen könntest - was nicht geht - würde das nur bewirken, dass das Bild nach rechts oder unten (oder bei dir oben) herausgeschoben wird.
Du musst wohl oder übel ans Bild ran und dann ggf. mit dem Ändern der Position und der Breite/Höhe agieren.
Stimmt. sie verändert sich von rechts und unten. Mein Fehler 😄
Das sich das Bild herausschiebt wäre kein Problem.
Was ich vielelicht noch dazusagen sollte. Das ganze ist kein Image in der picture Box sondern ein WebcamStream.
Ich glaube deshalb fast das diese Idee besser wäre, wenn man die pictureBox von OBEN und LINKS nicht verkleinern kann:
Rectangle zur Laufzeit über das iPad ziehen und dann z.B. auf einen Button klicken so dass die pictureBox sich genau auf den Rectangle-Bereich anpasst. Da hapert es aber leider an der Umsetzung weshalb ich ersteres präferieren würde.
Ein PictureBox stellt ein Bild dar, d.h. wenn du die Anzeige ändern willst, dann mußt du das Bild beschneiden, nicht die PictureBox.
Hier noch ein anderer Link: How to zoom an image in pictureBox? (ganz unten der funktionierende Code)
Dazu müssten wir erst einmal wissen, wie du den Video-Stream entgegen nimmst. - Die meißten Bibliotheken die ich kenne liefern nämlich Einzelbilder die man bearbeiten kann.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
using AForge.Video;
using AForge.Video.DirectShow;
private void Form1_Load(object sender, EventArgs e)
{
VideoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); // devicesstored in array
foreach (FilterInfo VideoCaptureDevice in VideoCaptureDevices)
{
comboBox1.Items.Add(VideoCaptureDevice.Name);
}
comboBox1.SelectedIndex = 0;
}
//void timer_Tick(object sender, EventArgs e)
//{
// throw new NotImplementedException();
//}
private void button1_Click(object sender, EventArgs e)
{
FinalVideoSource = new VideoCaptureDevice(VideoCaptureDevices[comboBox1.SelectedIndex].MonikerString);
FinalVideoSource.NewFrame += new NewFrameEventHandler(FinalVideoSource_NewFrame);
FinalVideoSource.Start();
}
void FinalVideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap image = (Bitmap)eventArgs.Frame.Clone();
pictureBox1.Image = image;
}
Hallo,
habe ich es mir doch gedacht. In FinalVideoSource_NewFrame hängst du doch ein Bild an die PictureBox. - Genau dieses Bild musst du eben auch entsprechend bearbeiten.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Hallo,
du kannst auch die PictureBox in ein Panel reinlegen und dann hinausschieben...
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Top -= 10;
}
private void button2_Click(object sender, EventArgs e)
{
pictureBox1.Top += 10;
}
private void button3_Click(object sender, EventArgs e)
{
pictureBox1.Left -= 10;
}
private void button4_Click(object sender, EventArgs e)
{
pictureBox1.Left += 10;
}
Die Picturebox kannst dann auf "SizeMode=Autosize" stellen.
Dann kannst Du noch die Größe von dem Panel extra ändern (Width und Height). (D.h. der Bildausschnitt wird größer).
Hi Elias1994,
das Zoomen ist doch völlig unabhängig von der Größe der PictureBox. Evtl. solltest du dir auch überlegen, ob eine PictureBox überhaupt das Richtige für diesen Anwendungsfall ist. Besser wäre es, das Zeichnen des Bildes so wie in [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox) umzusetzen. Dann kannst du auch gleich die richtige Überladung der Graphics.DrawImage-Methode verwenden, die einen bestimmten Ausschnitt aus einem Bild in einen bestimmten Ausschnitt auf die Form zeichnet. Damit sparst du dir die Nachbearbeitung der von der WebCam gelieferten Bilder.
Christian
Weeks of programming can save you hours of planning
Hallo zusammen,
habe nun ein Projekt gefunden mit dem das für ein Bild funktioniert.
Oben habe ich ja einen ja gepostet wie mein Webcamstream einbinde.
Wie muss ich den Code verändern, dass das auch für mein Video funktioniert?
Gruß,
Elias
In dem oben verlinkten Projekt wird das so gelöst:
public static Image Crop(this Image image, Rectangle selection)
{
Bitmap bmp = image as Bitmap;
// Check if it is a bitmap:
if (bmp == null)
throw new ArgumentException("Kein gültiges Bild (Bitmap)");
// Crop the image:
Bitmap cropBmp = bmp.Clone(selection, bmp.PixelFormat);
// Release the resources:
image.Dispose();
return cropBmp;
}
aber wie mache ich das für meinen Webcamstream?
Hi,
ganz ehrlich? Ich glaub deinen "eigenen" Code solltest du dir wirklich noch einmal anschauen... Du bindest nämlich mitnichten einen Stream an deine PictureBox - sondern machst bei jeder Bildaktualisierung ein neues Bild in deine PictureBox. Und mit diesem Bild - kannst du ungefähr machen was du möchtest.
Vorgehensweise:
static class ImageHelper
{
public static Image Crop(this Image image, Rectangle selection)
{
Bitmap bmp = image as Bitmap;
// Check if it is a bitmap:
if (bmp == null)
throw new ArgumentException("No valid bitmap");
// Crop the image:
Bitmap cropBmp = bmp.Clone(selection, bmp.PixelFormat);
// Release the resources:
image.Dispose();
return cropBmp;
}
}
void FinalVideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap image = (Bitmap)ImageHelper.Crop(eventArgs.Frame, new Rectangle(30, 30, 300, 300));
pictureBox1.Image = image;
}
LG
Uhh das Dispose in einer Helfterklasse.. da wäre ich vorsichtig.
Das ist von Außen überhaupt nicht erkenntlich und eher ungewöhnlich, dass das in so einer Methode passiert.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hey Taipi,
dein Ansatz sieht vielversprechend aus.
Das Rechteck zeichne ich mit Mousevents:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
// Starting point of the selection:
if (e.Button == MouseButtons.Left)
{
_selecting = true;
_selection = new Rectangle(new Point(e.X, e.Y), new Size());
}
}
//---------------------------------------------------------------------
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
// Update the actual size of the selection:
if (_selecting)
{
_selection.Width = e.X - _selection.X;
_selection.Height = e.Y - _selection.Y;
// Redraw the picturebox:
pictureBox1.Refresh();
}
}
//---------------------------------------------------------------------
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _selecting)
{
// Create cropped image:
Image img = pictureBox1.Image.Crop(_selection);
// Fit image to the picturebox:
pictureBox1.Image = img.Fit2PictureBox(pictureBox1);
_selecting = false;
}
}
//---------------------------------------------------------------------
Die Image Crop und Fit2Picturebox (s.MouseUp) habe ich jetzt in eine statische Klasse ausgelagert.
Fit2PictureBox:
public static Image Fit2PictureBox(this Image image, PictureBox picBox)
{
Bitmap bmp = null;
Graphics g;
// Scale:
double scaleY = (double)image.Width / picBox.Width;
double scaleX = (double)image.Height / picBox.Height;
double scale = scaleY < scaleX ? scaleX : scaleY;
// Create new bitmap:
bmp = new Bitmap(
(int)((double)image.Width / scale),
(int)((double)image.Height / scale));
// Set resolution of the new image:
bmp.SetResolution(
image.HorizontalResolution,
image.VerticalResolution);
// Create graphics:
g = Graphics.FromImage(bmp);
// Set interpolation mode:
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Draw the new image:
g.DrawImage(
image,
new Rectangle( // Ziel
0, 0,
bmp.Width, bmp.Height),
new Rectangle( // Quelle
0, 0,
image.Width, image.Height),
GraphicsUnit.Pixel);
// Release the resources of the graphics:
g.Dispose();
// Release the resources of the origin image:
image.Dispose();
return bmp;
}
}
Jetzt fehlt mir eigentlich nur noch void FinalVideoSource_NewFrame(object sender, NewFrameEventArgs eventArgs) anzupassen.
Kannst du mir da nochmal helfen?
Viele Grüße,
Elias
Ich verstehe wirklich nicht, warum du so einen Aufwand betreiben willst, wo doch ein Aufruf der DrawImage-Methode ausreichen würde, um den richtigen Bildausschnitt an der richtigen Stelle darzustellen.
Christian
Weeks of programming can save you hours of planning
Verwende ich doch. 😄 (s.o.)
Das Problem ist glaube ich, dass eben ständig neue Bilder erezugt werden, deshalb wirkt es ja wie ein Stream. Für ein Bild funktioniert das Ganze problemlos.
Du zeichnest ein Bild in ein anderes Bild, dafür verwendest du die Methode. Aber dann verwendest du zusätzlich noch die PictureBox, um das Bild darzustellen. In dem von mir verlinkten Artikel wird beschrieben, wie man stattdessen vorgehen sollte. Evtl. solltest du nochmal dort nachlesen, denn es erspart dir am Ende eine Menge Arbeit.
Daß in einem Video ständig neue Bilder angezeigt werden, ist ja irgendwie klar 🤔
In deinem ursprünglichen Code-Beispiel reagierst du doch auch darauf... Du mußt halt nur die Zuweisung des Bildes an die PictureBox ändern (bzw. stattdessen in der OnPaint-Methode zeichnen).
Irgendwie macht es den Eindruck, als würdest du lediglich Codeschnipsel aus dem Internet copy & pasten, ohne zu wissen, was der Code eigentlich genau macht.
Christian
Weeks of programming can save you hours of planning
Konnte das Problem jetzt lösen. Wer den Code brauch und in Zukunft auf dieses Thema stößt kann mir gerne eine PN schreiben.
Theo. wäre es vom Vorteil die Lösung des Problems hier zu erläutern falls jemand auf diese Problematik stößt.
Immerhin wurde Dir wohl erfolgreich geholfen bzw. wurdest Du zur Lösung erfolgreich begleitet.