Witajcie. Mam problem z małym Paintem w C#. Chcę rysować myszką prostokąt i wszystko działa, ale chciałbym żeby użytkownik przesuwając myszką widział zmianę kształtu. Jak przy rysowanieu prostokąta w prawdziwym Paincie.
Napisałem sobie kod, który to robi, ale od odrysowuje całe tło na biało (metoda Graphics.Clear()). Jak zrobić taki ficzer, żeby odrysowywało się początkowe tło, albo coś, żeby nie usuwało mi tego co już jest narysowane?
Ten kod rysuje prostokąt z odświeżeniem, ale czyści to co było rysowane wczesniej…
Point topRight = new Point(bottomRight.X, topleft.Y);
Point bottomLeft = new Point(topleft.X, bottomRight.Y);
Graphics g = pb.CreateGraphics(); //pb = picturebox
g.Clear(Color.White);
g.DrawPolygon(new Pen(new SolidBrush(Color.Pink), 3), new Point[] { topleft, topRight, bottomRight, bottomLeft });
g.Dispose();
Takiej funkcjonalności niestety w czystym GDI+ nie uświadczysz. Musisz to zaimplementować ręcznie.
Rozwiązaniem może być trzymanie kilku warstw(tutaj mogły by dwie wystarczyć - tło i zmieniający się prostokąt) i blitowanie ich przy zmianie jednej z nich(ale to też trzeba umiejętnie zrobić, bo może być ździebko niewydajne). Można też odświeżać tylko fragment PicruteBox’a, który się zmienia(czyli trzymać poprzedni prostokąt i czyścić tylko różnicę starego prostokąta i nowego, i rysować tylko różnicę nowego i starego; w sensie F1 - stary prostokąt, F2 - nowy prostokąt, czyścić: F1 \ F2; rysować: F2 \ F1).
I to jest problem… potrzebowałbym dwie “warstwy”. Tylko ta druga, do odświeżania musiałaby znów być czyszczona do białego - co nie rozwiązuje mojego problemu, albo musiałoby być przeliczane to co się pojawia na jednej i odrysowywanie różnic. Chyba nie chce mi się tego robić
Hm, będą do tego jakieś kontrolki tudzież zewnętrzne dll-ki?
“Blitując”? Czyszczenie na kolor przezroczysty skutkuje wypełnieniem do czarnego… Niby patrzę na OpenGl, coś skrobię, ale nadal nie wiem jak rozegrać tę kwestię
A rysujesz pod spodem (oś Z ) główny obrazek? (Takie rozwiązanie jest dobre gdy masz akcelerację sprzętową, np. OpenGl; Bez akceleracji lepiej blitować).
PictureBox nie obsługuje przeźroczystości, ale czyste GDI+ już tak. Wystarczy, że cały czas operujesz na System.Drawing.Image i na samym końcu uaktualniasz PictureBox.
Sample:
var bmpA = new Bitmap(600, 600); // Tło
var bmpB = new Bitmap(600, 600); // Kwadrat
using (var gB = Graphics.FromImage(bmpB))
{
gB.Clear(Color.Transparent);
gB.FillRectangle(Brushes.Red, 100, 100, 200, 200);
}
using (var gA = Graphics.FromImage(bmpA)) //Można(należy) użyć trzecią, wynikową powierzchnię, i to ją przypisywać do PB, ale tutaj tego nie potrzeba, więc pominąłem.
{
gA.Clear(Color.Blue);
gA.DrawImage(bmpB, 0, 0);
}
this.pictureBox1.Image = bmpA;