Laden...

C#-Anwendung - Bild mit Symbolen markieren und verändern

Erstellt von mierli vor 9 Jahren Letzter Beitrag vor 9 Jahren 3.634 Views
Thema geschlossen
M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren
C#-Anwendung - Bild mit Symbolen markieren und verändern

Hallo

Ich habe eine Frage zu Grafik-Programmieren, und mit diesem Thema bin ich nicht so sattelfest.
Es gibt eine C#-WinForms-Applikation, die um folgende Funktion erweitert werden muss:
-) Anzeige eines Bildes (in dem Fall ist es eine Darstellung vom menschlichen Körper).
-) Der Applikations-Benutzer soll verschiedenen Symbole (kleine Grafiken) auf diese Bild ziehen können, um so auf dem Körper verschiedene Regionen über Schmerzen und Veränderung der Schmerzen während der Therapie darstellen zu können.
-) Diese Symbole auf der Körper-Grafik sollen auf veränderbar sein / oder der Benutzer wieder löschen können (falls er etwas falsches zur falschen Körper-Region gezogen hat)
-) Diese gesamte Grafik (sprich Bild vom Körper) mit all den gesetzten Symbolen zu Markierung sollen in eine Datenbank gespeichert werden --> das ist aber kein Problem für mich....

So - jetzt habe ich einmal ein wenig herumprobiert, und habe als Grundlage ein UserControl mit dem Bild vom Körper auf einer Form gezeichnet. Dann habe ich die Symbole in Picture-Controls links davon angezeigt; und mit Drag&Drop das hinüberziehen einzelner Symbole auf die Körper-Grafik ausprogrammiert. Das funktioniert soweit mal.
Nur ich verändere damit das Körper-Bild selbst - und habe anschließend keine Kontrolle mehr über die Symbole auf der Körper-Grafik, um Symbole darauf zu verschieben oder zu löschen.


void OnTargetDragDrop(object sender, DragEventArgs e)
        {
            Point p = panelControl1.PointToClient(Cursor.Position);
            Point locationToDraw = new Point(p.X - viewInfo.ContentImageRectangle.Location.X, p.Y - viewInfo.ContentImageRectangle.Location.Y);
            Image image = e.Data.GetData(DataFormats.Bitmap) as Image;
            if (image == null)
                return;
            Bitmap bitmap = panelControl1.ContentImage as Bitmap;
            Bitmap newBitMap = new Bitmap(bitmap.Width, bitmap.Height);
            using (Graphics g = Graphics.FromImage(newBitMap))
            {
                g.DrawImage(bitmap, new Rectangle(0,0, bitmap.Width, bitmap.Height));
                g.DrawImage(image, locationToDraw);
            }

            MemoryStream ms = new MemoryStream();
            newBitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            list.Add(new BitmapPos() { dasBild = newBitMap, X = locationToDraw.X, Y = locationToDraw.Y });
            ms.Position = 0;
            bitmap.Dispose();
            panelControl1.ContentImage = Image.FromStream(ms);
            ms.Dispose();
        }

(hier ein Code-Ausschnitt aus dem OnTargetDragDrop()-Event, dass ich beim DragEnter vom UserControl auslöse)

Jetzt einmal meine grundsätzliche Frage -> bin ich so überhaupt auf dem richtigen Weg?? Ich glaube fast nicht.

Vielleicht kann mir hier im Forum bitte jemand weiterhelfen, der schon einige Erfahrung mit Grafik-Programmierung im .NET/C#-Bereich hat - und vielleicht hat jemand eine Idee, wie ich denn an diese Anforderung herangehen könnte.

Besten Dank schon mal & schönen Gruß
Michael

C
2.122 Beiträge seit 2010
vor 9 Jahren

Prinzipiell ist das schon ok, du erstellst dir ein Bild mit dem Körper und malst darauf die einzelnen Symbole.
Nur bitte nicht ganz so umständlich.
Halte dir "newbitmap" nur ein einziges mal statt es immer wieder neu zu erstellen. Bzw. halte wenn nötig noch ein Pufferbild damit die Anzeige sich nicht bei jedem Zeichenvorgang aktualisiert.

Warum die Sache mit dem MemoryStream? Image.FromStream gibt das zurück was du vorher in den Stream steckst, nämlich ein Bild. Also reicht panelControl1.ContentImage = newBitmap.

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo mierli,

arbeite zudem mit (mehr) Usings / IDisposable. Das macht dir das Leben nochmal einfacher.

Gruss

Coffeebean

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

Hallo Coffeebean und Chilic

Danke für Eure raschen Rückmeldungen!!
Das sind schon gute Tipps - aber nicht ganz die Antwort auf meine Fragen.

@Chilic -> Wenn ich mir ein Pufferbild behalte, dann muss ich für jeden Vorgang eine Kopie anlegen, um so zum vorigen Zustand zurück zu kommen.

Aber mein Problem ist ja - wenn ich mit dem aktuellen Demo Drag/Drop ein Symbol auf das Bild ziehe, ist es nachher nicht mehr änderbar; weil ich ja das Original-Bild wirklich verändere.

Ich dachte auch schon so: Alles was an Symbolen auf die Körper-Grafik gezogen wird extra abspeichern mit den jeweiligen Positions-Daten. Und so immer wieder die Grafik komplett neu aufbauen - d.h. die Körper-Grafik im Urzustand belassen und immer nur die Symbole mit deren Positions-Werten auf die Grafik malen.....

Aber da frage ich mich -- wie mache ich das ?
Und sind dann die gezeichneten Symbole noch änderbar vom Benutzer?

Schönen Gruß, Michael

16.842 Beiträge seit 2008
vor 9 Jahren

Du hast hier Anforderungen, die sich - in meinen Augen - abstoßen.

a) Wenn Du veränderbare Objekte haben willst, dann musst Du Dir jedes (Grafik)Objekt einzeln merken. Hinzu kommt, dass dies wahrscheinlich verwandt sein wird mit einem Undo-Pattern o.ä.
Du darfst halt das Originalbild nicht verändern; ist ja relativ simpel.
b) Wirst Du anschließend jedes Grafikobjekt einzeln zeichnen müssen. Wenn eine Grafik verschoben wird, und damit ein Teil eine anderern Grafik wieder sichtbar wird, muss dies zwangsläufig ebenfalls neu gezeichnet werden.

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

Hallo

ja - ok.
Aber was heißt das umgelegt auf die technische/Entwickler-Seite - welche Controls? Wenn es überhaupt mit den Standard-Controls möglich ist zu lösen.
(Wenn ich Symbole (was selbst eh auch wieder Grafik ist) auf eine Grafik ziehe, mir die Positions-Daten speichere um später wieder alles so darzustellen.....)

Wie gesagt, ich bin im programmieren von grafischen Objekten oder Grafik-Anforderungen nicht sattelfest...daher vielleicht auch etwas umständlich gefragt.

Schönen Gruß, Michael

4.221 Beiträge seit 2005
vor 9 Jahren

-Körpergrafik nicht speichern (die ist unveränderbar)
-Nur speichern welche Grafiken Du an welcher Stelle dazuzeichnen musst.
-Beim Repaint: 1 Körper zeichnen und dann alle zusätzlichen Grafiken

--> Es sieht dann so aus als wäre es eine Grafik... aber effektiv sieht es nur so aus

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

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

hallo programmierhans
danke für Deine Rückmeldung.
Genau in diese Richtung dachte ich auch schon.

Nur fehlt mir jetzt dazu das Wissen, mit welchen Controls das "dazuzeichnen" gemacht werden kann?
Und auch - sind die dazugezeichneten Grafiken/Symbole dann noch veränderbar - mit der Maus verschiebbar oder löschbar ???

gruß, Michael

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo mierli,

ich würde gar keine Controls verwenden, sondern alles direkt ins Form oder in ein Panel zeichnen. Alles was du wissen musst, steht in [Artikel] Zeichnen in Windows-Programmen und [Tutorial] Gezeichnete Objekte mit der Maus verschieben

herbivore

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

SUPER - Danke!!
das hilft mir schon mal weiter......

schönen Gruß, Michael

C
2.122 Beiträge seit 2010
vor 9 Jahren

Du musst von der Idee wegkommen, jedes Zwischenbild vorrätig zu halten um irgendwas verschieben zu können. Verschieben eines Elements passiert indem du das Bild komplett neu zeichnest. Das musst du öfter tun.
Daher wird das Körperbild gespeichert ohne es jedes mal neu zu laden. Das nimmst du als Ausgangsbild, die Symbole malst du immer da hin wo sie gerade sein sollen.
Klingt nach Aufwand, ist aber nicht anders zu lösen. Der Gedanke hier ein paar Controls aufs Bild zu legen ist zwar im ersten Moment richtig, bewirkt aber wenn man genau hinschaut genau das selbe.

Du hast die Elemente sowieso schon in "list", die nimmst du alle und zeichnest sie aufs Körperbild.
Du könntest das auch ständig in OnPaint deines Anzeigecontrols tun. Nachdem sich das recht oft zeichnen will und sich das zugrundeliegende Bild fast nie ändert, gibt es das Pufferbild. Das kann das Control als ganzes reinzeichnen wenn es will.

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

@chilic:

jetzt muss ich nochmals nachfragen:

*Du hast die Elemente sowieso schon in "list", die nimmst du alle und zeichnest *sie aufs Körperbild.

ja korrekt - das ist auch einfacher diese in der Datenbank zu speichern.

*Du könntest das auch ständig in OnPaint deines Anzeigecontrols tun. Nachdem *sich das recht oft zeichnen will und sich das zugrundeliegende Bild fast nie *ändert, gibt es das Pufferbild. Das kann das Control als ganzes reinzeichnen *wenn es will.

Da kann ich Dir jetzt nicht ganz folgen - mit den Pufferbild?
Ich dachte eher - beim Öffnen der WinForm lade ich zuerst das Hauptbild (die Körper-Darstellung) in ein UserControl oder PanelControl, und anschließend auf Grund der Positions-Daten zeichne ich die Symbole dazu....
Wäre das nicht so gut?

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo mierli,

es ist wie im Tutorial beschrieben. Du musst du dir den jeweils aktuellen Zustand merken, also insbesondere welche Symbole du an welche Stelle zeichnen willst. Im OnPaint zeichnest du dann immer alles, entsprechend dieses aktuellen Zustands direkt auf das Form (und nicht in ein Bitmap-Objekt). Solange du nicht gerade tausende oder mehr Symbole zeichnen musst, musst du auch nichts puffern. Das Hauptbild würde ich im OnPaint einfach als erstes zeichnen und die Symbole anschließend darüber.

herbivore

M
mierli Themenstarter:in
12 Beiträge seit 2006
vor 9 Jahren

Das Hauptbild würde ich im OnPaint einfach als erstes zeichnen und die Symbole anschließend darüber.

In meinem Fall würde das Hauptbild aus der Datenbank kommen - und das müsste ich dann in einem Control anzeigen. (kommt deshalb aus der Datenbank, weil es unterschiedliche "Haupt"-Bilder zu unterschiedlichen Situationen und Einstellungen gibt.

Aber das würde an der Sache nichts ändern.....- oder wie siehst das Du?

Hinweis von herbivore vor 9 Jahren

Ich sehe das so, dass du jetzt alle Informationen hast, die du braucht und die Nachfragen sich den Thread im Kreise drehen lassen. 😃 Es handelt sich hier um eine Standard-Aufgabe, deren Lösung durch die beiden (anfägerergeeigneten und -erprobten) Tutorials beschrieben wird.

Thema geschlossen