In Bildern durch Koordinaten Abstände messen

Terminator2

Erfahrenes Mitglied
Hallo,

Bin jetzt von VB 6.0 auf .Net umgestiegen. Ich arbeite im Moment noch mit der Express version bis ich die Standard habe. Aber hier meine Frage:

Ist es möglich, in einem ins Programm geladene Bild mittels dem Mauszeiger Abstände darin zu messen? Theoretisch ist das ja ganz einfach, man muss nur die Koordinaten von den zwei Mausklicks mit Phytagoras umrechnen und fertig. Aber wie mache ich das in .NET?

Hinterher soll dann mittels Umrechnungsfaktor aus den Pixelabständen Längeneinheiten gemacht werden.

Kann mir da jemand weiterhelfen? :)
 

Terminator2

Erfahrenes Mitglied
Hallo,

Bin inzwischen schon etwas weitergekommen. Ich dachte, hier würde gar keiner antworten, also schon mal danke.

Also folgendes will ich machen:

Es soll ein Bild von einer Kamera uÄ. importiert werden. Erst einmal nehme ich nur die Datei, hinterher werde ich die Kamera fernsteuern, aber das hat noch Zeit.

Ich habe jetzt erst einmal zwei Labels erzeugt, die bei MoveMouse die Koordinaten X / Y im Bild anzeigen. Das ist eine PictureBox. Das klappt auch schon. Die entfernungen berechne ich mit Phytagoras, nachdem ich per Mausklick 2 Koordinatenpunkte selektiert habe.

Das ist auch alles schon programmiert, also kein Problem. Aber nun das wichtigste:

Damit das Ganze benutzerfreundlich wird, soll nach Klick (Selektion) des ersten Punktes von diesem Punkt eine Linie mit der Maus verbunden werden, die immer an der Zeigerspitze hängt, bis der Benutzer einen zweiten Punkt ausgewählt hat.

Das ist mein Problem, theoretisch kein Problem, aber da ich in .NET neu bin.. :confused:

DANKE
 

Christian Kusmanow

Erfahrenes Mitglied
Damit das Ganze benutzerfreundlich wird, soll nach Klick (Selektion) des ersten Punktes von diesem Punkt eine Linie mit der Maus verbunden werden, die immer an der Zeigerspitze hängt, bis der Benutzer einen zweiten Punkt ausgewählt hat.
Sollte nicht so schwer sein. Zeichne bei jedem MouseMove Ereignis einen Pfeil vom Ausgangs- bis zum Endpunkt.
Schau Dir mal dieses nette Projekt an: C#: A-Star is born - Understand graphs and A* path-finding algorithm with C# - TheCodeProject. :)
 

Terminator2

Erfahrenes Mitglied
hört sich einfacher an als es ist ^^

Warum ist das denn so komplex? Mein Problem ist weniger das, wie ich zeichne, sondern mehr, wo der Code rein muss. Bei .NET sind die Deklarationen ja wieder ganz anders. Ich habe hier einen Code, wo alles wichtige drinnen ist, nur an falscher Stelle:

Hier mein aktuelles Programm *g*
Code:
Public Class Form1

    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Label1.Text = e.X
        Label2.Text = e.Y
    End Sub
End Class

Das mache ich mir der GDI+ (Was auch immer das ist)

Hier der Zeichen-Befehl
Code:
myGraphics.DrawLine(myPen, 4, 2, 12, 6)

Die Graphics-Klasse?!
Code:
Public NotInheritable Class Graphics
	Inherits MarshalByRefObject
	Implements IDeviceContext, IDisposable

und ihre Verwendung:
Code:
Dim instance As Graphics

Jetzt noch die Pen-Klasse
Code:
Public NotInheritable Class Pen
	Inherits MarshalByRefObject
	Implements ICloneable, IDisposable

und auch ihre Verwendung:
Code:
Dim instance As Pen

Wer mir das jetzt zusammenbastelt, sodass ich immer von einem Punkt (könnt ihr euch aussuchen, den verknüpfe ich später selbst, bis zum Mauszeiger eine Linie habe, dem poste ich ein nettes Smilie ;)

Also schonmal Danke :)
 

Terminator2

Erfahrenes Mitglied
Hallo,

Habe jetzt was bei Microsoft gefunden, was funtkioniert:

Code:
    Private Sub picturebox1_paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim p As New Pen(Color.Black)
        Dim g As Graphics = e.Graphics
        ' Eine Linie von (0,0) zu (500,500) zeichnen 
        g.DrawLine(p, 0, 0, 500, 500)
    End Sub

Das Problem ist aber, dass diese Linie nur beim Erstellen des Fensters gezeichnet wird, aber ich brauche eine, die nach Mausklick die Maus vom Klickursprung verfolgt. Das ist ja in jedem einfachen Zeichenprogramm möglich...
 

Christian Kusmanow

Erfahrenes Mitglied
So, ich hab Dir schnell mal eine kleine Demo gemacht. Hier mal ein Auszug aus dem Control was ich erstellt habe. Ich hab hier einiges bewusst weggelassen. ;)
C#:
public class MyCustomOwnerDrawnControl : Control
{
	/**/
	// Definieren der nötigen Objekte.
	Point
		m_point = Point.Empty,
		m_mousePoint = Point.Empty;

	Pen m_pen;

	public MyCustomOwnerDrawnControl( IContainer container )
	{
		/**/

		Init();
	}

	void Init()
	{
		// ControlStyle auf händisches Zeichnen einstellen. Dies kann man nur innerhalb des Construktor-Aufrufs.
		// Zusätzlich siehst noch diverse Einstellungen die denke ich mal selbsterklärend sind.
		SetStyle(
			ControlStyles.UserPaint |
				ControlStyles.AllPaintingInWmPaint /*|
				ControlStyles.DoubleBuffer |*/
				/*ControlStyles.ResizeRedraw*/,
			true );
	}

	// Wenn linke Maustaste gedrückt werden die Koordinaten gespeichert.
	protected override void OnMouseDown( MouseEventArgs e ) und der Pen initialisiert.
	{
		if( e.Button == MouseButtons.Left ){
			m_point.X = e.X;
			m_point.Y = e.Y;
			m_pen = new Pen( Color.Black );
		}
		base.OnMouseDown( e );
	}

	// Wenn linke Maustaste los gelassen werden die Koordinaten gelöscht.
	// Ganz wichtig! Immer das Pen Objekt nach der Verwendung disposen,
	// um Speicher zu sparen.
	protected override void OnMouseUp( MouseEventArgs e )
	{
		if( e.Button == MouseButtons.Left ){
			m_point = Point.Empty;
			m_pen.Dispose();
			m_pen = null;
		}
		base.OnMouseUp( e );
	}

	// Bei jeder Bewegung der Maus wird die Position gespeichert und das Zeichnen des Controls ausgelöst.
	protected override void OnMouseMove( MouseEventArgs e )
	{
		m_mousePoint = new Point( e.X, e.Y );
		base.Invalidate();
	}

	// Zeichnet die Linie sofern die linke Maustaste gedrückt wurde.
	protected override void OnPaint( PaintEventArgs e )
	{
		if( m_point == Point.Empty || m_pen == null )
			return;
		e.Graphics.DrawLine( m_pen, m_point, m_mousePoint );
		base.OnPaint( e );
	}
}
 

Anhänge

  • PaintLineDemo.zip
    59,1 KB · Aufrufe: 72

Terminator2

Erfahrenes Mitglied
Hi,

alle achtung, haste ja perfekt hinbekommen. Ich versuche mal das irgendwie in mein VB.NET zu importieren?! :confused:

Ich hab nämlich keine Ahnung ob und wie das geht...

Also erstmal Danke für das schöne Programm. Kann man das Ganze denn auch in einer PictureBox machen? müsste doch gehen, oder?


mfg
 

Christian Kusmanow

Erfahrenes Mitglied
Damit kannst Dir das auch in VB.NET anschauen :) :
[thread=255334]Wichtig: C# zu VB.net, und umgekehrt.. - Stickie[/thread]
Reflector for .NET

//Edit: Klar kannst das auch mit einer PictureBox machen. Tausche einfach den Typ Control, von dem MyCustomOwnerDrawnControl ableitet, genen den Typ PictureBox aus. Die PictureBox basiert ja auf dem Typ Control. ;)

//Edit: Weist Du eigentlich, wie Du in dein VS benutzdefinierte Steuerelemente einbindest, damit Du sie aus der ToolBox in den Designer "ziehen" kannst?
 
Zuletzt bearbeitet:

Terminator2

Erfahrenes Mitglied
Hi,

Also einfach gesagt: Ich weiß gar nichts bis auf VB6.0 ;)
Kommt drauf an was du meinst. Also ich kenne diese Controls wie zB. Timer usw.
Aber ich habe mit Visual Studio noch gar nichts programmiert, außer eine PictureBox mit Koordinatenanzeige. :suspekt:

Werde das gleich mal ausprobieren.

mfg