[VB.net/C#] In Picturebox malen ähnlich wie bei Paint

Alaitoc

Erfahrenes Mitglied
Hallo,
wollte mal fragen ob es möglich ist so in etwa
in ne Picturebox zu malen wie bei z.b. Paint.
Habe hier und anderorts zwar ähnliche Themen gefunden,
aber eher für Linien und Rechtecke.

Schonmal Danke :)

PS: Sprache ist egal C# oder VB.net
 
Hab hier mal was kleines gemacht ist zwar nicht ganz genau aber funktioniert zumindest :rolleyes:

Code:
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.list = new List<Point>(); //Liste für Koordinaten instanziieren
            this.bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            pictureBox1.Image = bmp;
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            mouseDown = true;
            list.Add(new Point(e.X, e.Y));
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                mouseDown = false;
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    Draw(g);
                    g.Flush(); 
                }
                list.Clear();
                pictureBox1.Invalidate();
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                list.Add(new Point(e.X, e.Y));
                pictureBox1.Invalidate();
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (mouseDown)
                Draw(e.Graphics);
        }

        /// <summary>
        /// zeichnen
        /// </summary>
        private void Draw(Graphics g)
        {
            using (SolidBrush sb = new SolidBrush(Color.Black))
            {
                foreach (Point pt in list)
                {
                    if (g.VisibleClipBounds.Contains(pt))
                        g.FillRectangle(sb, new Rectangle(pt.X, pt.Y, 2, 2));
                }
            }
        }

        private bool mouseDown; //ob Maustaste gedrückt wird (zur Speicherung der Maus koordinaten)
        private readonly List<Point> list; //Mauskoordinaten
        private readonly Bitmap bmp; //Bitmap zum speichern des gezeichneten
    }
denke mal ist eigentlich selbst erklärend
 
Habs ein bissel verfeinert, jetzt sollten keine Freiräume beim zeichnen mehr erscheinen.

Code:
/// <summary>
/// zeichnen
/// </summary>
private void Draw(Graphics g)
{
    if (list.Count > 0)
    {
        byte[] bs = new byte[list.Count];
        bs[0] = (byte)PathPointType.Start;
        for (int i = 1; i < list.Count; i++)
            bs[i] = (byte)PathPointType.Line;

        using (Pen p = new Pen(Color.Black, 2))
            g.DrawPath(p, new System.Drawing.Drawing2D.GraphicsPath(list.ToArray(), bs));
    }
}
 
Hallo Spyke,

ich habe dein oben geschriebenen Code verwendet und weiterentwickelt und bin auf ein Problem gestossen, wo du mir vielleicht helfen kannst.

Ziel:
Mein Ziel ist es ein Programm zu schreiben, dass beim öffnen einen Screenshot vom Desktop macht und diesen in der Picturebox anzeigt. (funktioniert) Anschließend will ich mit einem "Stift" auf die Picturebox mit dem geladenenen Bild malen (wie in Paint). Dabei dir dein Code verwendet. Zum Schluss soll dann wieder ein Screenshot erstellbar sein.

Problem:
Das Problem ist er zeichnet es wie gewünscht, nur wenn ich die Maus loslasse verschwindet meine gezeichnete Linie wieder und es ist nur das Bild sichtbar. Hast du ein Idee an dem es liegen könnte. Ich kann dir auch den Quellcode geben.

Danke schonmal für deine Bemühungen.
 
Ich denke mal du hast vergessen das als im Bitmap zu "speichern"

PHP:
using (Graphics g = Graphics.FromImage(bmp))
                {
                    Draw(g);
                    g.Flush(); 
                }

Dort lasse ich mir das Graphics Objekt vom Bitmap zurückgeben (Bitmap wird auch für anzeige in PictureBox verwendet).
Zeichne auf dem Graphics Objekt (Draw Funktion).
Und mit Flush wird sozusagen das Zeichnen erzwungen.
http://msdn2.microsoft.com/en-us/library/system.drawing.graphics.flush.aspx

Ev. auch noch die Funktion Invalidate der PictureBox aufrufen damit Bild neu dargestellt wird.

Spyke (www.iv-interactive.de)
 
Hallo Spyke,

danke für deine Antwort. Ich habe aber

Code:
using (Graphics g = Graphics.FromImage(bmp)) 
                { 
                    Draw(g); 
                    g.Flush();  
                }
diesen Code drinnen. Ausserdem habe auch rausgefunden das der Aufruf

pictureBox1.Invalidate();

mir mein gezeichnetes löscht. Wenn ich den Funktionsaufruf rausschmeiße, dann ist die Linie da. Aber wenn ich eine zweite machen möchte löscht er mir dann die erste. Damit du dir das Problem besser anschauen kannst habe ich dir mein Projekt angehängt.

Ich bedanke mich schonmal für deine Bemühnungen.
 

Anhänge

  • testmalen.zip
    82,8 KB · Aufrufe: 520
Hm also ich musste mit ner Liste arbeiten, wo ich immer die neue Linie hinzugeschrieben habe und dann
alle neu reingeladen habe.
 
Das Problem ist du übergibst zwar meine Bitmap aber lädst danach ein neues Bild, intern wird ein neues Bitmap geladen, womit mein bmp eigentlich überflüssig wurde.
PHP:
pictureBox1.Image = bmp;
            try
            {
                pictureBox1.Load("c:/Dokumente und Einstellungen/All Users/Anwendungsdaten/tmp.bmp");
               
                
            }
            catch (Exception x)
            {
                MessageBox.Show("Exception " +x.Message);
            }

so funktionierts
PHP:
this.bmp = new Bitmap("c:/Dokumente und Einstellungen/All Users/Anwendungsdaten/tmp.bmp");
            pictureBox1.Image = bmp;

Spyke (www.iv-interactive.de)
 
Zurück