Laden...

paint-ähnlichen Stift programmieren

Erstellt von jHammer vor 15 Jahren Letzter Beitrag vor 14 Jahren 4.891 Views
J
jHammer Themenstarter:in
14 Beiträge seit 2008
vor 15 Jahren
paint-ähnlichen Stift programmieren

Hallo zusammen,

ich wollte ein recht einfaches Bildbearbeitungsprogramm programmieren.
Ich habe jetzt erstmal (weil wir das in der Schule bisher nur gelernt haben) mit Create.Graphics() gearbeitet. Ich habe hier im Forum schon den Artikel mit Paint/OnPaint gelesen. Werde aber noch nicht so richtig schlau aus ihm. Ich bin halt noch ein totaler Anfänger.

In der Schule haben wir bisher nur Strings "gemalt". (siehe Kommentar im Code)
Jetzt wollte ich aber, dass ich einen "Stift" habe. So wie der Stift in Paint.

Hier dazu der Code:

private void hauptfenster_MouseClick(object sender, MouseEventArgs e)
        {
            if (stift_an == 1)
            {
                Graphics graph = CreateGraphics();
                //graph.DrawString("0", newFont, Brushes.Chocolate, e.X, e.Y);
                double Y = e.Y;
                double X = e.X;
                PointF y_x = new PointF(e.X, e.Y);
                System.Drawing.Pen myPen;
                myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
                graph.DrawLine(myPen, y_x); 
                               
            }        
        }

Ich scheitere noch an diesem "PointF". Ich weiß nicht, wie ich dem die aktuelle Mausposition übergebe.
Ich habe es auch schon so probiert. Dann meckert er aber, dass ich PointF nur ein Argument übergebe:

PointF y = new PointF(e.Y);
                PointF x = new PointF(e.X);
                System.Drawing.Pen myPen;
                myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
                graph.DrawLine(myPen,y,x); 

Ihr habt bestimmt eine viel elegantere Lösung. Ich brauch wirklich eure Hilfe. Vielleicht könnte mir ja auch jemand dieses Paint/OnPaint mal idiotensicher erklären.

3.511 Beiträge seit 2005
vor 15 Jahren

Das hier [Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox) sollte dich erstmal weiter bringen

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

J
jHammer Themenstarter:in
14 Beiträge seit 2008
vor 15 Jahren

Das hier
>
sollte dich erstmal weiter bringen

s.o.

Ich habe hier im Forum schon den Artikel mit Paint/OnPaint gelesen. Werde aber noch nicht so richtig schlau aus ihm. Ich bin halt noch ein totaler Anfänger.

946 Beiträge seit 2008
vor 15 Jahren

hallo jHammer

Schau es dir nochmal an 😉

Ich bin halt noch ein totaler Anfänger.

Ich könnte dich jetzt auf [Hinweis] Wie poste ich richtig? Punkt 1.1.1 hinweisen. Mache ich auch :evil:

Im Artikel steht, dass man e.Graphics verwenden sollte, und darum nur im Paint-Event zeichnen kann. Mit Invalide() kannst du das Neuzeichnen erzwingen.

Ich scheitere noch an diesem "PointF". Ich weiß nicht, wie ich dem die aktuelle Mausposition übergebe.

Hast du schon. Warum möchtest du es ein zweites Mal?

Um einen Punkt zu zeichnen, verwendest du einfach ein Rechteck mit der Seitenlänge 1.

Ich empfehle dir das 🛈 und das 📗 . Die sind gratis.

mfg
SeeQuark

S
13 Beiträge seit 2008
vor 15 Jahren

Wenn du einen "paint-ähnlichen Stift" (freihandlinie) programmieren willst, dann wäre eine Möglichkeit bei jedem MouseMove- Event die aktuelle Mouse Position abzufragen und in eine Liste einzutragen. In OnPaint zeichnest du dann mit DrawLines oder so Linien zwischen den gespeicherten Punkten.

Ich empfehle dir aber erst nochmal alle von meinen Vorrednern genannten Links durchzuarbeiten.

J
jHammer Themenstarter:in
14 Beiträge seit 2008
vor 15 Jahren

Im Artikel steht, dass man e.Graphics verwenden sollte, und darum nur im Paint-Event zeichnen kann. Mit Invalide() kannst du das Neuzeichnen erzwingen.

Dann müsste das ganze doch so aussehen, oder?

private void hauptfenster_Paint(object sender, PaintEventArgs e)
        {
            if (stift_an == 1)
            {
                Size größe = new Size(1, 1);
                Point mausposition = new Point(MousePosition.X, MousePosition.Y);
                Rectangle punkt = new Rectangle(mausposition, größe);
                Pen mypen = new Pen(System.Drawing.Color.GreenYellow);
                e.Graphics.DrawRectangle(mypen, punkt);
                Invalidate();
                
                //graph.DrawString("0", newFont, Brushes.Chocolate, e.X, e.Y);
            }
        }
49.485 Beiträge seit 2005
vor 15 Jahren

Hallo jHammer,

im Paint solltest du nie Invalidate aufrufen.

Du solltest den Ansatz von Seb19 verfolgen.

herbivore

E
1 Beiträge seit 2009
vor 14 Jahren

Also ich denke ma, dass du immer noch den Cursor als Pinsel benutzen willst. Um wem Programm zu sagen, dass er auf der PictureBox malen soll, musst du ein Ereigniss erstellen.
Das sogenannte MouseOver. Du musst ihm allerdings vorher sagen, dass wenn du einen Mausklick machst, zu einem Punkt wird:

        private void malfeld_MouseDown(object sender, MouseEventArgs e)
        {
            p1 = e.Location; //e ist der Cursor. e weiß wo der cursor ist!
        }

Und jetzt passiert das malen:

private void malfeld_MouseMove(object sender, MouseEventArgs e)
           {
            if(e.Button == MouseButtons.Left) //Wenn Mausklick links
            {
            m_gr.DrawLine(new Pen(m_farbe, m_stärke), p1, e.Location); //m_farbe //kann auch Color.Red oder so und m_stärke ne zahl. Hab halt über ComboBox ne  //auswahl gemacht gehabt.
            malfeld.Image = m_bmp; //In die Picutrebox das Bitmap geben
            p1 = e.Location;//damit er nicht von einem Punkt ausgeht sonderne einem  //neuen
            }

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo eifelenergY,

es reicht nicht im MouseMove zu malen, weil dann das Gemalte z.B. nach einem Minimieren des Bildes wieder weg ist. Siehe auch [Artikel] Zeichnen in Windows-Programmen.

herbivore

C
3 Beiträge seit 2006
vor 14 Jahren

also im ctor folgedens aufrufen:


SetStyle(ControlStyles.AllPaintingInWmPaint|
			         ControlStyles.DoubleBuffer|
			         ControlStyles.ResizeRedraw|
			         ControlStyles.UserPaint|
			         ControlStyles.SupportsTransparentBackColor, // nur wers transparent braucht
			         true);

mein maximieren wird automatisch die paint methode aufgerufen da s.o ResizeRedraw gesetzt ist.

die position des cursors würde ich via mousemove holen.

das zeichen für den Click würde ich wie folgt erledigen:

  1. variable für den mouseclick und mousemove deklarieren:

private bool bMouseDown;
private int xMouse,yMouse;

  1. beim OnMouseDown Event:
 
protected override void OnMouseDown(MouseEventArgs e)
{
   bMouseDown = true // mouse gedrückt
   this.Invalidate() // neu zeichnen
}

  1. beim OnMouseUp Event:
  
protected override void OnMouseUp(MouseEventArgs e)
{
   bMouseDown = false // mouse nicht mehr gedrückt
   this.Invalidate() // neu zeichnen
}

  1. aktuellen coordinaten bekommt ihr über das OnMouseMove-Event. (selbes handling wie bei MouseDown (var deklarieren...))

protected override void OnMouseMove(MouseEventArgs e)
{
   xMouse = e.X;
   yMouse = e.Y;
}

  1. dann nur zeichnen im OnPaint wenn bMouseDown true ist....
 
protected override void OnPaint(PaintEventArgs e)
{
   base.OnPaint(e);
   if(bMouseDown == true)
   {
       e.Graphics.DrawRectangle(new Pen(SystemBrushes.Black,1f),xMouse,yMouse,1,1);
   }
}

wer in der Paint Methode Invalidate aufruft erzeugt einen DeadLock -> endlos zeichnen so dass ihr nix mehr seht 😉....

hoffe ich konnte helfen 😃

so far bless it