Laden...

Unterschiede: In Form oder picutreBox zeichen

Erstellt von Dr.Z vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.600 Views
Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 16 Jahren
Unterschiede: In Form oder picutreBox zeichen

Hallo zusammen,

ich beschäftige mich momentan mit dem Zeichnen in c#. Ich will nichts aufwendiges machen, sondern nur verschiedene Zahlen und Buchstaben malen und bestimmte Punkte zu lokaliseren (höchster gemalter Punkt, tiefster gemalter Punkt usw...).

Jetzt gibt es ja zwei Möglichkeiten zu Zeichen:

  1. in das Form an sich.
  2. in das Image einer PictureBox.

Ich wusste nicht, wie ich in der Form an die bemalten Pixel heran kommen sollte. Also habe ich zusätzlich ein zweidimensionales bool Array erstellt, welches die Maße der Form hat und jedes Element, in das auf der oberfläche Zeichne, auf true gesetzt. Um nun nachher die oben genannten Punkte zu lokalisieren, durchsuche ich einfach nur das Array nach bestimmten Kriterien. Das klappt auch ganz gut und geht sehr schnell.

Um in der PicureBox, bzw. dem Image der PictureBox an die Pixel zu gelangen, die ich "bemalt" habe, gehe ich wie folgt vor:


for (int y = 0; y <= bmp.Height - 1; y++)
            {
                for (int x = bmp.Width; x >= 0; x--)
                {
                    col_pixel = bmp.GetPixel(x, y);

                    if (col_pixel.Name != "0")
                    {
                        pnt_oben.X = x;
                        pnt_oben.Y = y;
                        bol_pixelfound = true;
                        break;
                    }
                }

                if (bol_pixelfound == true)
                {
                    break;
                }
            }

bmp ist das Image der PictureBox und eine Instanz der Klasse Bitmap.
Ich frage halt jedes Pixel ab, ob es schwarz ist oder nicht. Da gibts bestimmt noch ne bessere Lösungsmöglichkeit, habe aber erstmal keine gefunden, so als Laie.
Auch mit dieser Methode lassen sich meine Punkte (höchster gemalter Punkt, tiefster gemalter Punkt usw...) finden. Nur dauert das sehr sehr lange.

Ansich ist das kein Problem, ich finde das Zeichnen in eine PictureBox aber besser, da ich meiner Meinung nach mehre Optionen in der weiteren Verarbeitung des Bildes habe.

Meine Frage lautet eigentlich nur (und dafür so viel Text 🙂 ) warum entsteht ein so ein großer Zeitunterschied beim Suchen von bestimmten Punkten zum einen in einem Array und zum anderen in einem Image. Letztendlich sind die Pixel der Bitmap doch auch nichts anderes als ein zwei dimensionales Array?

Würde mich sehr über eure Antworten freuen

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Dr.Z,

GetPixel ist lahm. Siehe GetPixel und SetPixel um Längen geschlagen. 800 mal schneller

herbivore

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 16 Jahren

Danke für den sehr interessanten Link. Damit kann ich auf jedenfall was anfangen und werde es auch versuchen umszusetzen. 👍

Jedoch sind meine Fragen noch nicht damit beantwortet, so richtig 🙂

...warum entsteht ein so ein großer Zeitunterschied beim Suchen von bestimmten Punkten zum einen in einem Array und zum anderen in einem Image. Letztendlich sind die Pixel der Bitmap doch auch nichts anderes als ein zwei dimensionales Array?

Vielen Dank

Z

4.506 Beiträge seit 2004
vor 16 Jahren

Hallo Dr.Z,

...warum entsteht ein so ein großer Zeitunterschied beim Suchen von bestimmten Punkten zum einen in einem Array und zum anderen in einem Image. Letztendlich sind die Pixel der Bitmap doch auch nichts anderes als ein zwei dimensionales Array?

Weil ein Bitmap vielleicht doch nicht wirklich ein Array ist 😉 Ein Bitmap ist ein Datenstrom. Darin zu suchen ist teuer (zeitintensiv). Ein Array legt eine Struktur an, mit dessen Hilfe man auch per Index an die jeweiligen Stellen direkt zugreifen kann. Das geht in einem Datenstrom eben nicht.

Genauer: Ein Bitmap gibt seine Bildgröße mit an. Da das aber Variabel ist, kann man nicht "blind" z.B. von einer Zeile in die nächste Springen, sondern man muss sich eine gewisse Anzahl an Pixeldaten vorwärts durchhangeln. In einem Array existiert ein Index auf die nächste Zeile, so dass direkt dorthin gesprungen werden kann.

Aber unter bestimmten Vorraussetzungen hast Du recht: Wenn man ALLE Pixeldaten verarbeiten/untersuchen möchte, dann ist sogar ein Datenstrom schneller, weil man auf Indizes keine Rücksicht nehmen muss.

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

Dr.Z Themenstarter:in
88 Beiträge seit 2007
vor 16 Jahren

Danke für deine Antwort, diese war sehr hilfreich und verständlich. 👍
Mal gucken wie ich mein Problem nun lösen werde, habe ja jetzt mehrere Methode, wie man es machen kann.

Danke dir nochmals.

Eine allgemeine Frage zum verlinkten Artikel hätte ich noch:
Es kommt eine Zeile wie folgt im Quellcode vor:

RoBitmap robmp = new RoBitmap();

Ich finde die Klasse RoBitmap nirgends. Finde nur die Standard "Bitmap".
Kann mir da noch jemand weiter helfen?

Danke euch.

Dr. Z

P
13 Beiträge seit 2005
vor 16 Jahren

Hi,

wenn ich das richtig sehe, ist das die Klasse aus der DLL, die du in dem Artikel runterladen kannst...

K
13 Beiträge seit 2008
vor 16 Jahren

Weil ein Bitmap vielleicht doch nicht wirklich ein Array ist 😉 Ein Bitmap ist ein Datenstrom.

Oh weh. Da hast du aber was mißverstanden, oder? Eine Bitmap ist ein feststehender Block von Daten, den man durchaus auch als Array betrachten kann.

Darin zu suchen ist teuer (zeitintensiv). Ein Array legt eine Struktur an, mit dessen Hilfe man auch per Index an die jeweiligen Stellen direkt zugreifen kann. Das geht in einem Datenstrom eben nicht.

Ebenfalls falsch.

Gruß,

Klaus

4.506 Beiträge seit 2004
vor 16 Jahren

Hallo Klaus L.,

schön, dass Du mich hier korrigierst, davon profitiert dei Gemeinschaft am Meisten. Würdest Du anstatt zu sagen, "das ist falsch" auch die richtige Antwort dazu geben?

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo norman_timo,

die richtige Antwort ist, dass eine Bitmap auf Header und Pixeldaten besteht, wobei die Pixeldaten in einem Memory-Block derart gespeichert sind, dass man mit

(Zeilenlänge in Bits * y) + (x * Bits pro Pixel)

auf das erste Bit des Pixels an Bildposition (x,y) zugreifen kann. Bei vielen Bildformaten ist "Bits pro Pixel" ein vielfaches von 8, so dass man mit

(Zeilenlänge in Bytes * y) + (x * Bytes pro Pixel)

auf das erste Byte des Pixels Bildposition (x,y) zugreifen kann.

Die Zeilenlänge in Bits ergibt sich aus der

Breite des Bilds in Pixeln * Bits pro Pixel, nötigenfalls aufgerundet auf die nächstgrößere durch 32 teilbare natürliche Zahl.

Die Zeilenlänge in Bytes ergibt sich aus der

Zeilenlänge in Bits / 8.

Sprich, bis auf das Padding der Zeilen auf volle vier Bytes, liegen die Pixeldaten dicht an dicht, können aber - da alle Zeilen gleich lang sind - auch als zweidimensionales Array betrachtet werden.

herbivore

4.506 Beiträge seit 2004
vor 16 Jahren

Hallo Herbivore,

danke für die ausführliche Antwort. Der Aufbau war mir zwar bewusst, jedoch muss eben der Header zuvor ausgewertet werden, damit solch eine Adressierung vorgenommen werden kann.

Ich habe es soweit ausdrücken wollen, dass ohne Auswertung des Headers das Bitmap nicht direkt zu adressieren ist.

Aber ich habe auch nur in meinem Studium einmal den Fall gehabt, dass wir Bitmaps direkt verarbeitet haben, und dort haben wir einfach festgelegt, wie groß eine Pixelinformation und wie groß das Bild war, und so konnten wir das direkt einlesen, wäre aber bei einem anderen Bildformat auf die Schnauze gefallen.

Aber dass ein Bitmap zunächst ein Stream darstellt würde ich nicht als falsch bezeichnen (auch wenn durch den Header eine direkte Adressierung vorgenommen werden könnte).

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo norman_timo,

Aber dass ein Bitmap zunächst ein Stream darstellt würde ich nicht als falsch bezeichnen

nö, nicht falsch, nur irreführend 🙂 denn in der Ausgangsfrage ging es ja um ein Bitmap-Objekt, das schon im Speicher existiert. Da sind sowohl Header als auch Pixeldaten schon eingelesen. Die Pixeldaten liegen somit in der schon beschriebenen Array-Form vor und die für den Zugriff nötigen Informationen aus dem Header liegen aufbereitet vor. Zu diesem Zeitpunkt spielt die Datenstrom-Sicht keine Rolle mehr, denn selbst komprimierte Formate wie GIF- und JPG, deren Datenstrom-Form einigem Aufwand beim direkten Zugriff verursachen würde, wurden ja dann schon in die unkomprimierte Array-Form umgewandelt.

herbivore

4.506 Beiträge seit 2004
vor 16 Jahren

Hallo Herbivore,

denn in der Ausgangsfrage ging es ja um ein Bitmap-Objekt, das schon im Speicher existiert.

oh oh, sehe ich ein (ich bin von einer direkten Auswertung ohne Bitmap-Objekt ausgegangen).

Notiz an mich:
Bitte Ausgangsfragestellung immer komplett und genau durchlesen.
-> Ich ertappe mich in letzter Zeit häufiger darin, dass ich das nicht tue (ich hab zu viel um die Ohren)

Sorry für die Verwirrung und danke für die Klarstellung.

Gruß
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

K
13 Beiträge seit 2008
vor 16 Jahren

Würdest Du anstatt zu sagen, "das ist falsch" auch die richtige Antwort dazu geben?

Die richtige Antwort habe ich provoziert und das hat auch funktioniert. Eigentlich wäre es ja die Aufgabe eines Moderators gewesen, daraufhinzuweisen, dass deine Ausführungen falsch waren, insbesondere da sich ja bereits jemand für die falsche Antwort bedankt hatte. Ich habe selbst nicht vollständig geantwortet, weil meine Kommentare teilweise zensiert werden. Da ich ja nicht weiß, welchen Teil der Herr Zensor wegschneidet, schreib ich halt einfach nur wenig.

Übrigens bleibt die Bitmap auch ohne Header eine Bitmap. Es gab Zeiten da hatten Bitmaps keinen Header.

Gruß,

Klaus

476 Beiträge seit 2004
vor 16 Jahren

Hallo Klaus L.,

Eigentlich wäre es ja die Aufgabe eines Moderators gewesen, daraufhinzuweisen, dass deine Ausführungen falsch waren, insbesondere da sich ja bereits jemand für die falsche Antwort bedankt hatte. Ich habe selbst nicht vollständig geantwortet, weil meine Kommentare teilweise zensiert werden. Da ich ja nicht weiß, welchen Teil der Herr Zensor wegschneidet, schreib ich halt einfach nur wenig.

weder Herr Zensor noch dessen Frau zensiert "einfach Dir nichts mir" nichts Beiträge. Bitte unterlasse diese Unterstellung künftig. Viel netter wäre es gewesen sich direkt an die Moderatoren zu wenden.

-yellow

Selbst ein Weg von tausend Meilen beginnt mit einem Schritt (chinesisches Sprichwort).

Mein Blog: Yellow's Blog auf sqlgut.de

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Klaus L.,

Eigentlich wäre es ja die Aufgabe eines Moderators gewesen, daraufhinzuweisen, dass deine Ausführungen falsch waren

das ist eine sehr merkwürdige Sicht dessen, was die Aufgabe eines Moderators ist.

weil meine Kommentar_e_ teilweise zensiert werden.

Hier die Mehrzahl zu verwenden ist genauso irreführend wie die Verwendung des Worts Zensur. Es wurde genau ein Beitrag von dir gekürzt und zwar deshalb, weil du darin Werbung gemacht hattest. Genau dieser Werbeteil und nicht mehr und nicht weniger wurde aus dem Beitrag entfernt. Der eigentliche Beitrag blieb bei vollem Sinngehalt erhalten. Besonders dreist war diese Werbung deshalb, weil du spätestens aus einer PM von mir schon wusstest, dass (dir) solche Werbung nicht erlaubt ist. Diese PM hatte ich dir geschickt, nachdem ich deinen ersten Beitrag hier im Forum entfernt hatte, weil er ausschließlich aus Werbung bestand.

Also gibt deine Fehler bitte nicht als unsere aus.

herbivore