Hallo,
ich habe eine Picturebox mit dem maß 300x300 Pixel und ein Bild mit 1000x1000 Pixel. Jetzt möchte ich ein Ausschnitt des Bildes (eben nur 300x300 Pixel gross) in die picturebox laden, allerdings mit folgenden Bedingungen:
Ich gebe von dem 1000x1000 Bild eine x/y Koordinate vor und genau die Koordinate soll der Mittelpunkt meiner 300x300 großen picturebox sein.
Ist das möglich?
Grüße Mr.Ed
Du kannst die Option umstellen auf strech mode. Dann sollte das gehen.
Codexzier
Nicht immer hilft Wissen weiter, manchmal muss man einfach daran glauben.
Die originalgrößte muss erhalten bleiben, ich möchte ja nur einen Ausschnitt zeigen. Stretch Mode passt ja nur die Bildgröße an wenn ich mich nicht irre?
Achso, das stimmt. Das hab ich selbst noch nicht raus. 8o
Nicht immer hilft Wissen weiter, manchmal muss man einfach daran glauben.
Hallo Mr.Ed,
Wenn es nichts anderes gibt, so kannst du auch hier meine Klasse verwenden.
Habe dazu gerade eine Methode geschrieben und getestet:
public Bitmap GetPieceOfImage(Rectangle rect)
{
Bitmap tmpBitmap = new Bitmap(rect.Width, rect.Height);
RoBitmap tmpRoBitmap = new RoBitmap(tmpBitmap);
for (int x = rect.X; x < rect.X + rect.Width && x < Width; x++)
for (int y = rect.Y; y < rect.Y + rect.Height && y < Height; y++)
tmpRoBitmap.SetPixel(x - rect.X, y-rect.Y, GetPixel(x, y));
return tmpRoBitmap.Image;
}
Die musst du dann noch dazu packen. 😉
Einfach dann von dem Bild eine RoBitmap machen, oder es damit laden. Dann z.B:
pictureBox1.Image = rob.GetPieceOfImage(new Rectangle(480,100,240,240));
Und schon ist der gewünschte Ausschnitt in der pictureBox
Gruß Robert
Geht auch viel einfacher und vermutlich schneller...
=>Bitmap.Clone()
@ Mr.Ed
Habe oben den Link zugefügt. Ganz unten ist die neueste Fassung. Man kann alles mögliche mit dem Bild anstellen. Wenn ich Zeit habe oder wie hier Bedarf sehe erweitere ich immer ein bischen. =)
Und @marsgk
Ist 800 mal schneller in GetPixel und SetPixel.
Wenn ich mich nicht irre, hat er mit Bitmap.Clone() ja auch nur eine Kopie und keinen Ausschnitt.
Gruß Robert
Ich meine ja auch Bitmap.Clone(Rectangle, PixelFormat)
Creates a copy of the section of this Bitmap defined by Rectangle structure and with a specified PixelFormat enumeration.
Man muss ja nicht alles neu erfinden...
Original von marsgk
Man muss ja nicht alles neu erfinden...
Da hast du absolut Recht!!!
Wenn es das schon gibt, braucht man es nicht. Ich wusste das noch nicht.
Gruß Robert
Wo finde ich Deine Klasse? Würde mich tierisch freuen wenn das klappt !!
//Bitmap Class
Bitmap.Clone (Rectangle, PixelFormat)
//Creates a copy of the section of this Bitmap defined with a specified PixelFormat.
private void Clone_Example1(PaintEventArgs e)
{
// Create a Bitmap object from a file.
Bitmap myBitmap = new Bitmap("Grapes.jpg");
// Clone a portion of the Bitmap object.
Rectangle cloneRect = new Rectangle(0, 0, 100, 100);
System.Drawing.Imaging.PixelFormat format =
myBitmap.PixelFormat;
Bitmap cloneBitmap = myBitmap.Clone(cloneRect, format);
// Draw the cloned portion of the Bitmap object.
e.Graphics.DrawImage(cloneBitmap, 0, 0);
}
@sarabande
private void Clone_Example1(PaintEventArgs e)
Was muss ich denn an die Funktion übergeben? Sorry wenn ich so blöde frage, aber für mich ist das alles neuland. Ich lerne jeden Tag dazu...!
myPictureBox.Image = myImage.Clone(new Rectangle(10, 10, 100, 100), myImage.PixelFormat);
@Robertico
Ich habs erstma mit Deinen Code vorhin probiert, das klappt auch soweit super. Nur ein Problem bleibt. Die X/Y Koordinate die ich in deinem Code übergebe entspricht ja der linken oberen Ecke des Bildausschnitts. Allerdings soll bei mir die Koordinate ja genau in der Mitte des Bildausschnitts zu sehen sein.
Ne idee?
@marsgk
Nein !!! Bitte nicht böse sein falls dies den Eindruck erweckt hat, der Grund ist einfach das ich Deine Tipps und Angaben noch nicht ausprobiert habe. Ich hab mich erst mit dem Code von Robertico beschäftigt. Bin wirklich für jede Hilfe hier dankbar.
Original von marsgk
myPictureBox.Image = myImage.Clone(new Rectangle(10, 10, 100, 100), myImage.PixelFormat);
OK funzt, das Problem das die Koordinate links oben ist und nicht in der Mitta habe ich wie folgt gelöst:
Da meine picturebox 240x240 Pixel groß ist zieh ich von dem Zielbild einmal 120 bei x ab und 120 bei y. Dann ist es wie gewünscht in der Mitta. Passt. 😁
Hallo Alle,
Habe von marsgk auch schon gelernt. Zum Dank.
@marsgk; wenn man im Stress ist übersieht man einiges bzw. kommt einiges zusammen, dass man den Überblick verliert.
Habe mal ein kleines Projekt gemacht, in dem man mit Reglern den Bildauschnitt verschieben kann.
Links ist meine Version, rechts ist Bitmap.Clone(...)
Zeitunterschiede kann ich nicht feststellen. Vorteile sehe ich aber bei meiner Version, da man keine Sicherung mehr einbauen muss. Die ist schon drin.
In dem Zusammenhang gibt es etwas keineres als** Environment.TickCount** ?
Gruß Robert.
Original von Robertico
@marsgk; wenn man im Stress ist übersieht man einiges bzw. kommt einiges zusammen, dass man den Überblick verliert.
Kenn ich nur zu gut...
Ich hab mich halt nur gewundert.
Zeitunterschiede kann ich nicht feststellen. Vorteile sehe ich aber bei meiner Version, da man keine Sicherung mehr einbauen muss. Die ist schon drin.
Ich habe beim ersten Mal übersehen, dass du da eine eigene Bitmap-Implementierung verwendest. Darum habe ich mir nur gedacht, dass die Clone Methode wohl schneller sein muss als x-Mal Get/Set-Pixel aufzurufen.
In dem Zusammenhang gibt es etwas keineres als** Environment.TickCount** ?
Ich kenn nur die QueryPerformaceCounter
Funktion. Im .Net Framework hab ich die allerdings noch nicht angetroffen.
Edit: Bei Codeproject gefunden:
=> http://www.codeproject.com/csharp/highperformancetimercshar.asp
Danke für den Tip.
Habe es ausprobiert. Demnach ist die original Version ca. 20% schneller.
Wer also nichts anderes anstellen will mit dem Bild ist besser bei der Clone-Version aufgehoben. (weil einfacher da schon drin)
Werde aber noch feilen. 😁 . Mag Schnelligkeit.
Gruß Robert
@Mr. Ed: Ich nehme an, es geht dir immer noch um dein Navigationssystem. Dann hast du wohl den letzten Satz meiner Antwort in Wie realisiert man die Bewegung der Karte von Navi Systemen? überlesen.
Daher wiederhole ich ihn hier noch einmal:
Dazu kannst du bei einigen der Überladungen von Graphics.DrawImage() angeben, welcher Bereich einer Bitmap gezeichnet werden soll.
Damit sparst du dir das vorherige Kopieren und kannst direkt in deine PictureBox zeichnen.
@Borg
Danke für den Hinweis. Ich hab gar nicht gemerkt das mir geantwortet wurde, wohl keine Benachrichtigung für den Thread aktiviert.
Ich versuch mich mal in Graphics.DrawImage() einzuarbeiten. Falls jemand noch irgendwo im weiten Netz ein schönes einfaches Beispiel dazu hat, her damit... 🙂
Was würde ich als Noob nur machen ohne Euch... 😁 👍