Laden...

Bild zentrieren

Erstellt von rs4 vor 18 Jahren Letzter Beitrag vor 18 Jahren 7.137 Views
R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren
Bild zentrieren

Hallo zusammen!

Mein Problem ist eigentlich schnell erklärt:

Ich habe eine Picturebox und darin ist logischerweise ein Bild eingebunden. Das läuft, ich kann das Bild auch zoomen.

Nun, ich möchte, dass wenn ich auf einen Punkt des Bildes klicke, dieser Punkt zum Mittelpunkt der Picturebox wird. Hat jemand einen Ansatz wie man das am besten bewerkstelligt??

Ich habe mir überlegt, dass ich das ganze ins PictureBox -- MouseUP-Ereignis packe...aber dann ist schon Feierabend, ich muss irgendwie die Mauskoordinaten zum Mittelpunkt machen, hab aber kein Plan wie....Ist auch nur meine Überlegung, vielleicht hat jemand einen besseren Vorschlag??

Jegliche Hilfe ist willkommen!

Danke im Voraus!

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Also, ich hab mal versucht den beschriebenen Weg einzuschlagen...einiges hab ich hinbekommen, anderes nicht...es ist mir gelungen, die Mausposition zu speichern, jetzt muss ich diese Koordinaten irgendwie als Mittelpunkt der Picturebox festlegen...und da klemmts....

hier mal mein Code:

private void pictureBox1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			double xPos = Control.MousePosition.X;
			double yPos = Control.MousePosition.Y;

			//Nur zum testen
			this.textBox1.Text = xPos.ToString();
			this.textBox2.Text = yPos.ToString();

			//Hier gehts nicht weiter...
			//Mittelpunkt der Picturebox muss Koordinaten der MousePosition erhalten
			this.pictureBox1.Image....
		}

Probier ich hier etwas das gar nicht funktikonieren kann, oder bin ich nahe dran???

Hoffe jemand sieht eine Lösung...

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Also, hab alles versucht, bekomms nicht hin....

hab wirklich einen Knopf, und ähnliche Problemstellungen finde ich auch nicht... 🙁

Wenn jemand einen Vorschlag hat....wäre wirklich super.

Auf meine Art funktionierts glaube ich nicht....

4.221 Beiträge seit 2005
vor 18 Jahren

Also MouseUp liefert ja Screen-Koordinaten

Diese mit PictureBox1.PointToClient in ClientCoordinaten umwandeln (dann haste die Positon innerhalb der PictureBox)

Offset berechnen und die Lage der PictureBox neu festlegen

(PictureBox1.Location = .....)

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Aha...hab zwar nicht alles verstanden, aber DANKE für deine Antwort!!

Juhu, jetzt kann ich weiterpröbeln, und versuchen alles zu verstehen!

gebe dann Bescheid wies rausgekommen ist!

Nochmals vielen Dank!

Grüsse

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Na gut, ist doch nicht so einfach....im Grunde hab ichs Verstanden was es tut, das Bild verschiebt sich auch schon (oder indirekt die Box, so wie ich das verstanden habe...

Point p = new Point(e.X, e.Y);

			//Nur zum testen
			this.textBox1.Text = p.X.ToString();
			this.textBox2.Text = p.Y.ToString();

			//Hier gehts nicht weiter...
			//Mittelpunkt der Picturebox muss Koordinaten der MousePosition erhalten

			this.pictureBox1.Location = this.pictureBox1.PointToClient(p);

Was ich noch nicht ganz kapiere ist, wie ich die Location verändern muss, du hast irgendwie gemeint offset berechnen....wo liegt bei mir der Fehler? Mir ist klar das die Locationzuweisung falsch ist, weiss aber nicht wie ich das richtigbiegen könnte...

Ich versuch mal weiter, aber wenns noch einen Zustztipp geben würde, wäre ich nicht böse... 🙂

Grüsse

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

aha...jetzt hab ich rausgefunden was falsch läuft...ich verschieb ja die ganze Picturebox in meinem GUI....kann das so wirklich funktionieren??? Muss ich sozusagen eine PictureBox in der Picturebox machen, damit ich dann die ganze Box verschieben kann....

jetzt wirds kompliziert... 8o

P
939 Beiträge seit 2003
vor 18 Jahren

Hast du Scrollbalken? Wenn ja, könntest du die SetDisplayRectLocation-Methode des ScrollableControls (oder einer ScrollableControl-Ableitung), das die Scrollbalken bereitstellt, verwenden.

Ich weiss nicht genau wie die PictureBox-Klasse ihre Scrollbalken bekommt. Von ScrollableControl ableiten, tut sie jedenfalls nicht. Also vermute ich, dass sie in ein ScrollableControl eingebettet ist.

Gruss
Pulpapex

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Nein, die habe ich nicht...

Ich versuche so ne Art Stadtplan nachzubauen... Ich habe also ein Bild, dass grösser ist als meine Picturebox, und wenn ich nun auf einen Punkt des Bildes klicke, soll es, wie aus Stadtplänen üblich zum Mittelpunkt werden, und das Bild richtig verschieben...

Mit der Lösung vom Programmierhans verschiebe ich ja die ganze Picturebox im GUI, was mich etwas verwirrt....

Ich möchte keine Scrollbalken, nur die oben erwähnte Lösung, wenn das möglich ist...(Also möglich ist ja fast alles....)

Sitze schon den ganzen Tag dran, mir sind die Ideen ausgegangen... 🙁

(Aber lösen will ich das Problem!!!!)

P
939 Beiträge seit 2003
vor 18 Jahren

Dann musst du es wohl so machen:

Im Programm gibt es ein grosses Original-Image, in der PictureBox befindet sich nur ein kleineres Arbeits-Image mit dem Bildausschnitt. Bei einem Mausklick ins Bild wird dann aus dem Original-Image der aktuelle Ausschnitt ins Arbeits-Image kopiert. In das Arbeits-Image kann man mit Graphics.FromImage(workingImage) zeichnen. Dran denken, dass das gelieferte Graphics-Objekt unbedingt und so schnell wie möglich mit Dispose wieder freigegeben werden muss (using()-Block).

Gruss
Pulpapex

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

gut, ich bin jetzt einigermassen verwirrt! 😁

Ich versuche mich mal schlauer über die Stichworte von dir zu machen....hoffe es wird erfolgreicher als meine vorherigen Versuche.

Danke vielmals für die Tipps, ich melde mich bestimmt wieder!

Gruss
rs4

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo rs4,

ich hoffe, das folgende entwirrt dich:


using System;
using System.Windows.Forms;
using System.Drawing;

//*****************************************************************************
public class Canvas : Form
{
   //--------------------------------------------------------------------------
   private PictureBox _picbCanvas;
   private Panel      _pnlCanvas;
   //==========================================================================
   public Canvas ()
   {
      Control ctrlCurr;

      Text = "PictureBox";
      ClientSize = new Size (640, 480);

      //-----------------------------------------------------------------------
      ctrlCurr = _pnlCanvas = new Panel ();
      ctrlCurr.Location = new Point (0, 0);
      ctrlCurr.Size = ClientSize;
      ctrlCurr.Anchor = AnchorStyles.Left | AnchorStyles.Right
                      | AnchorStyles.Top | AnchorStyles.Bottom;
      Controls.Add (ctrlCurr);

      //-----------------------------------------------------------------------
      ctrlCurr = _picbCanvas = new PictureBox ();
      ((PictureBox)ctrlCurr).SizeMode = PictureBoxSizeMode.AutoSize;
      ((PictureBox)ctrlCurr).Image = (Bitmap)Image.FromFile (@"map.bmp");
      ctrlCurr.MouseDown += new MouseEventHandler (CanvasMouseDown);
      ctrlCurr.Location = new Point (_pnlCanvas.Width/2-ctrlCurr.Width/2,
                                     _pnlCanvas.Height/2-ctrlCurr.Height/2);
      _pnlCanvas.Controls.Add (ctrlCurr);

      //-----------------------------------------------------------------------
      MaximumSize = new Size (_picbCanvas.Width  + Width  - ClientSize.Width,
                              _picbCanvas.Height + Height - ClientSize.Height);
   }
   //==========================================================================
   protected void CanvasMouseDown (Object sender, MouseEventArgs me)
   {
      _picbCanvas.Left = _pnlCanvas.Width/2-me.X;
      _picbCanvas.Top  = _pnlCanvas.Height/2-me.Y;
   }
}

//*****************************************************************************
abstract class App
{
   public static void Main (string [] astrArg)
   {
      Application.Run (new Canvas ());
   }
}

Die PicturePox ist immer so groß wie das Bild. Die Poition der gesamten PictureBox wird beim Klick so geändert, dass die geklickte Stelle in der Mitte des Panel angezeigt wird. Das Panel ist hat eine feste Position und Größe (bis auf die Größenänderung durch die Anchor, die man aber weglassen könnte).

Die Position der PictureBox ändert zwar, die des Panels aber nicht; ich denke damit hat mal alles unter einem Hut.

herbivore

PS: Es muss sich eine Bitmap-Datei map.bmp im gleiche Verzeichnis befinden oder man muss den Dateinamen an eine andere bestehende Bilddatei anpassen.

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Danke erstmal Herbivore für deine Mühen!

Ich habe nun mit allen Tipps es einigermassen hinbekommen. Habs mit der DrawImage methode dann so hinbekommen, dass es nun einigermassen das tut, was es auch soll...

Ein Problem stellt sich noch. Wenn ich die MouseUp-Methode generiere, gelingt es mir, die Mauskoordinaten zu bekommen (e.X, e.Y).... Wie kann ich jedoch extern auf diese zugreifen??Ich kann sie ja nicht als Rückgabewert angeben....

Vermutlich sitze ich schon zu lange an dem Problem, jedoch wenn jemand gerade die Lösung für ausstehendes Problem hat...

Wäre nicht böse drum!

Nochmals vielen vielen Dank für all eure Hilfe, wäre sonst nie drauf gekommen! 👍

1.549 Beiträge seit 2004
vor 18 Jahren

wie wäre es wenn du eine Klassen Variable erzeugst in die du dann speicherst

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

jep, das versuch ich auch...mach aber irgendwas falsch...:

ich generiere die Klassenvariabel:

//Mausposition
		private int MousepX = 0;
		private int MousepY = 0;

Danach versuche ich darin zu speichern, und zwar so:

private void pictureBox1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			this.MousepX = e.X;
			this.MousepY = e.Y;

			this.textBox1.Text = this.MousepX.ToString();
			this.textBox2.Text = this.MousepY.ToString();
		}

Ich glaube, dass das auch funktioniert, weil in den beiden Textboxen der Wert ändert, jedoch kommt das Ganze in der Paintmethode nicht an???...

private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
....	
//Bild wird mit gewählten Attributen gezeichnet
		e.Graphics.DrawImage(plan, this.MousepX, this.MousepY, srcRect, units);
....

Hier bleiben die Variabeln aber auf 0, oder werden irgendwie nicht aktualisiert...

Wird vielleicht diese Methode nicht immer aufgerufen? Muss ich da was manuell machen, oder hab ich was übersehen?

Danke für die Hilfe.

Grüsse

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Alles klar, hab was gefunden, habs jetzt mit Refresh() gelöst, weiss nicht ob das elegant ist, aber wenigstens zeichnet er es jetzt neu, wenn ich mit der Maus aufs Bild klicke, jedoch noch nicht richtig...aber das Problem ist jetzt mehr mathematischer Natur....

private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			//Mittelpunkt ermitteln
			int x = this.MousepX;
			int y = this.MousepY;

			//Plan wird geladen
			Bitmap plan = new Bitmap(Image.FromFile(Application.StartupPath + "\\Winter.gif"));

			//Grösse & Position des Bildausschnittes
			Rectangle srcRect = new Rectangle(0, 0, this.pictureBox1.Width, this.pictureBox1.Height);

			GraphicsUnit units = GraphicsUnit.Pixel;

			//Bild wird mit gewählten Attributen gezeichnet
			e.Graphics.DrawImage(plan, x, y, srcRect, units);
		}

Jetzt sieht es so aus, dass der Mittelpunkt nicht dort ist wo ich klicke, sonder er setzt mir die linke obere Ecke des Bildes an die Stelle wo ich geklickt habe...

Ist mir auch klar wieso, da ich ja den Startpunkt verschiebe...wie kann ich jedoch das Bild so verschieben, dass einfach dies Position welche ich angeklickt habe, zum Mittelpunkt wird, und nicht diese Ecke???

Ich schaue nochmals Herbivores Lösungsvorschlag an, aber das ist mir eine Stufe zu hoch...

P
939 Beiträge seit 2003
vor 18 Jahren

Hi rs4,

die Mauskoordinaten müssen noch in Image-Koordinaten umgerechnet werden. Das Ganze ist einfache Vektorarithmetik im Control-Koordinatensystem. Es gibt drei Vektoren: Center-Vektor (Control-Mittelpunkt), Mouse-Vektor (Mausposition) und Image-Vektor (Bildposition). Mouse-Vektor minus Center-Vektor ergibt einen Verschiebungsvektor. Dieser muss zum aktuellen Image-Vektor addiert werden, das ergibt die neue Bildposition.

Ich habe mal schnell eine Grafik gebastelt, die das veranschaulicht.

Gruss
Pulpapex

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Aha..."einfache Vektorgeometrie"... 😁

Ich schau das mal in Ruhe an, geb dann Bescheid, ob ichs auch geschanllt habe!

Vielen vielen Dank für deine Mühen!

Grüsse

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Ok, also verstanden hab ich es...aber funktionieren tuts noch nicht so recht...(was vermutlich bedeutet, dass ich es doch nicht ganz verstanden habe)...

Habs dank deiner Skizze mal so gemacht:

//Mittelpunkt ermitteln
			Point Mausvektor = new Point(this.MousepX, this.MousepY);
			Point Centervektor = new Point(this.pictureBox1.Width/2, this.pictureBox1.Height/2);
			Point Bildvektor = new Point(0, 0);
			Point Verschiebungsvektor = new Point(0, 0);

			Verschiebungsvektor.X = Mausvektor.X - Centervektor.X;
			Verschiebungsvektor.Y = Mausvektor.Y - Centervektor.Y;

			Bildvektor.X = Bildvektor.X + Verschiebungsvektor.X;
			Bildvektor.Y = Bildvektor.Y + Verschiebungsvektor.Y;

Zeichnen tu ichs dann folgendermassen:

e.Graphics.DrawImage(plan, Bildvektor.X, Bildvektor.Y, srcRect, units);

Ich glaube dass ich einen Fehler beim Bildvektor mache, oder wie ich den einbinde...

Programmverhalten: Es wird nicht zentriert, sondern bringt mir immer den gleichen Kartenpunkt zur Mausposition...Ich versuchs mal weiter, hoffe dass ich drauf komme, so nahe an der Lösung war ich bis jetzt noch nicht!

Nochmals vielen Dank! 😉

P
939 Beiträge seit 2003
vor 18 Jahren

Das wird daran liegen, dass du Bildvektor jedes Mal wieder mit new Point(0, 0) initialisierst. Der Vektor muss als Membervariable in der Klasse vorgehalten werden, da aus der letzten Bildposition und der aktuellen Mausposition die neue Bildposition ermittelt wird.

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

Jep Danke, daran hab ich auch schon gedacht, und die Variabel "global" definiert, aber macht trotzdem nicht was es sollte....

ich überlege grade, ob das mit Mausposition - Mittelpunkt alle Fälle abdeckt, wenn ich das nachher summiere... ich probier einfach mal weiter, wenigstens tut sich was, und die Motivation ist noch das 😁

Vermutlich ist es simpel, aber ich hab da noch nicht den vollen Durchblick, entschuldige mich dafür....

Grüsse

R
rs4 Themenstarter:in
87 Beiträge seit 2005
vor 18 Jahren

JUHUUUUU!!!!

Es läuft...endlich...und was war das Problem??? Gar nix, optisch sieht es so aus als würde er es falsch machen, hab mir aber die nötigen Koordinaten ausgeben lassen, und sie verglichen, und es tut was es tun soll, der geklickte Punkt wird zum Zentrum!

Einfachste Vektorgeometrie eben.... 😁

Danke vielmals allen die mir hier geholfen haben! (War vermutlich nicht das letzte mal)

Finde kein Smiley, dass so smilet, wie ich gerade, aber freue mich riesig darüber dass es geklappt hat!!

Grüsse!