Rysowanie i malowanie C#

0

Chciałbym namalować koło w pictureBox1, lub też móc malować za pomocą klasy pen linie. Niestety mam błąd w moim kodzie w metodzie pictureBox1_Paint.

Error 1 'System.Drawing.Graphics' does not contain a definition for 'Graphics' and no extension method 'Graphics' accepting a first argument of type 'System.Drawing.Graphics' could be found (are you missing a using directive or an assembly reference?)

Proszę o pomoc w poprawieniu tego kodu.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Graphics g;
        Point mold, mcur;
        public Form1()
        {
            InitializeComponent();
            pictureBox1.Image = new Bitmap(300, 345);
            g = Graphics.FromImage(pictureBox1.Image);
            Pen pioro = new Pen(Color.Black);
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mold = e.Location;
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mcur = e.Location;
                Invalidate();
            }
        }
        private Rectangle rec(Point p1, Point p2)
        {
            Rectangle a = new Rectangle();
            a.X = (p1.X > p2.X ? p2.X : p1.X);
            a.Y = (p1.Y > p2.Y ? p2.Y : p1.Y);
            a.Width = Math.Abs(p1.X - p2.Y);
            a.Height = Math.Abs(p1.Y - p2.Y);
            return a;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            g.Graphics.DrawEllipse(Pens.Black, rec(mold, mcur));
        }


    }
}
 
0

nie g.Graphics tylko e.Graphics
i naucz sie cztac co do ciebie mowi kompilator

0

Wiem dawałem już zmienną e, ale wtedy działa jakoś dziwnie. Raz że mam myszkę w innym miejscu to on i tak maluje sobie w swoim. Jakoś dużo centymetrów obok. A dwa, że pierwsze namalowane koło znika. A chciałbym by było jedno po kliknięciu we wskazanym moim miejscu, które mógłbym powiększać do pÓÓÓÓki nie puszczę lewego klawisza myszy. Potem jak puszczę to powinienem malować drugie obok tego. Taki efekt chciałbym osiągnąć. Proszę o pomoc w poprawieniu tego kodu.

0

Raz że mam myszkę w innym miejscu to on i tak maluje sobie w swoim. Jakoś dużo centymetrów obok.

MouseEventArgs.Location Property
Gets the location of the mouse during the generating mouse event.

Property Value
Type: System.Drawing.Point
A Point that contains the x- and y- mouse coordinates, in pixels, relative to the upper-left corner of the form.

0

Trochę ruszyłem do przodu i nie wiem co dalej. Dlatego proszę o pomoc. Niestety kwadrat rysuje się z wypełnieniem (pełno linii w środku) jak na zdjęciu. Jak to zrobić by nie malowało się to w środku? proszę o poprawienie mojego kodu lub jakieś sugestie.

user image

Tak teraz przedstawia się kod:

 namespace WindowsFormsApplication1
{


    public partial class Form1 : Form

    {
        private Graphics g;
        private Point mold;
        private Point p = Point.Empty;
        private Pen pioro;

        public frmMiniPaint()
        {
            InitializeComponent();
            pictureBox1.Image = new Bitmap(400, 400);
            g = Graphics.FromImage(pictureBox1.Image);
            pioro = new Pen(Color.Black);
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                p = e.Location;
                mold = e.Location;
                

        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
             
                g.DrawRectangle(pioro, rec(mold, p));
                
                p = e.Location;
                
                pictureBox1.Refresh();
            }
        }
        private Rectangle rec(Point p1, Point p2)
        {
            Rectangle a = new Rectangle();
            a.X = (p1.X > p2.X ? p2.X : p1.X);
            a.Y = (p1.Y > p2.Y ? p2.Y : p1.Y);
            a.Width = Math.Abs(p1.X - p2.Y);
            a.Height = Math.Abs(p1.Y - p2.Y);
            return a;
        }


    }
}
0

Nie rysuje się z wypełnieniem, tylko rysuje się wiele razy jak przeciągasz myszkę. Musisz przed każdym narysowaniem prostokąta wyczyścić płótno.

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                /*czyszczenie płótna, coś w stylu g.Clear(); a może pictureBox1.Clear()
                nie wiem jak dokładnie to będzie wyglądało w C#, it's up to you to find out*/
                g.DrawRectangle(pioro, rec(mold, p));
 
                p = e.Location;
 
                pictureBox1.Refresh();
            }
        }
0

Spine
Mnie chodzi o taki efekt jak masz w Windowsowskim Paintcie. Czyli klikasz w jeden punkt i przeciągasz góra, dół, lewo prawo a ten kwadrat będzie się rozszerzał lub zmniejszał. Ostateczna forma namaluje się dopiero kiedy puszczę myszkę. I to jest efekt którego pragnę. Ale jest pewien problem, bo w moim błędnym kodzie linijka p = e.Location cały czas zwraca następne położenie myszki i po czym znowu działa linijka g.DrawRectangle(pioro, rec(mold, p)); i ciągle rysuje kolejny kwadrat od tego nowego punku (co widać na rysunku wyżej) bo jesteśmy w metodzie void pictureBox1_MouseMove, która odpowiada za ruch myszy. Metoda void pictureBox1_MouseDown odpowiada za to że jest wciśnięty klawisz. I to właśnie wszystko tworzy takie błędne koło.

Muszę coś z tym zrobić by nie malował się kolejny kwadrat dopóki nie przestanę przeciągać tego pierwszego i nie puszczę lewego klawisza mysz. Tylko, że ja nie mam na to pomysłu. Ponadto nie jestem biegły w C# a raczej jestem amatorem który się uczy dopiero. Stąd ten temat i moja prośba do osób bieglejszych niż ja nad pomocą rozwiązania tego problemu.

0

Na MouseDown pobierasz współrzędne środka i tworzysz kopię istniejącego obrazu.
Na MouseMove przerysowujesz: nowy obraz = kopia + nowy okrąg.
Na MouseUp obraz = kopia + finalny okrąg; kopia == null;

0

j_s_r_n
Dzięki ale trochę to lakonicznie wytłumaczyłeś, bo niestety mało zrozumiałem.
"Współrzędne środka"? Masz na myśli współrzędne środka tego kwadratu co chce narysować?
"Tworzysz kopię istniejącego obrazu"? Kopia tej bitmapy? Jakiego to ma być typu?

Prosił bym o jakieś przykłady na kodzie, bo takie rzeczy lepiej mnie się analizuje.

0

Miałem na myśli okrąg.
Ależ mi się dzisiaj nie chce pracować.

public partial class Form1 : Form
    {
        bool Rysujemy;
        Bitmap KopiaObrazka;
        Point Wspolrzedne;

        public Form1()
        {
            InitializeComponent();
            Bitmap obrazek = new Bitmap(PBobrazek.Width, PBobrazek.Height);
            Graphics graphics = Graphics.FromImage(obrazek);
            Brush brush = Brushes.White;
            graphics.FillRectangle(brush, 0, 0, obrazek.Width, obrazek.Height);

            PBobrazek.Image = obrazek;
        }

        private void PBobrazek_MouseDown(object sender, MouseEventArgs e)
        {
            Rysujemy = true;
            Wspolrzedne = e.Location;
            KopiaObrazka = PBobrazek.Image.Clone() as Bitmap;
        }

        private void PBobrazek_MouseMove(object sender, MouseEventArgs e)
        {
            if (Rysujemy)
            {
                Bitmap obrazek = KopiaObrazka.Clone() as Bitmap;
                Graphics graphics = Graphics.FromImage(obrazek);
                Pen pen = new Pen(Color.Black, 2);
                graphics.DrawRectangle(pen, PoliczProstokat(e.Location));
                PBobrazek.Image = obrazek;
            }
        }

        private Rectangle PoliczProstokat(Point nowyPunkt)
        {
            int lewyGornyX = (Wspolrzedne.X > nowyPunkt.X) ? nowyPunkt.X : Wspolrzedne.X;
            int lewyGornyY = (Wspolrzedne.Y > nowyPunkt.Y) ? nowyPunkt.Y : Wspolrzedne.Y;
            int szerokosc = Math.Abs(Wspolrzedne.X - nowyPunkt.X);
            int wysokosc = Math.Abs(Wspolrzedne.Y - nowyPunkt.Y);
            Rectangle prostokat = new Rectangle(lewyGornyX, lewyGornyY, szerokosc, wysokosc);

            return prostokat;
        }

        private void PBobrazek_MouseUp(object sender, MouseEventArgs e)
        {
            Rysujemy = false;
            Bitmap obrazek = KopiaObrazka.Clone() as Bitmap;
            Graphics graphics = Graphics.FromImage(obrazek);
            Pen pen = new Pen(Color.Black, 2);
            graphics.DrawRectangle(pen, PoliczProstokat(e.Location));
            PBobrazek.Image = obrazek;
        }
    }
 
0

Dzięki j_s_r_n wszystko działa. Temat można zamknąć.

0

Prosty błąd - jeśli rysujesz linię to nie chcesz pracować na pierwotnej wersji obrazka tylko na aktualnej.
Wystarczy, że zamienisz:

Bitmap obrazek = KopiaObrazka.Clone() as Bitmap;

w metodach MouseMove i MouseUp na:

Bitmap obrazek = ((wybor==1)?KopiaObrazka.Clone():KopiaObrazka) as Bitmap;

1 użytkowników online, w tym zalogowanych: 0, gości: 1