Transparent panel i zrzut części ekranu

Odpowiedz Nowy wątek
2018-02-11 13:04
0

Mam na formie paintbox na którym użytkownik rysuje linie. Potrzebuję jakiejś przezroczystej kontrolki (może to być panel lub Timage lub inna) na którą nakładam siatkę linii, a cały komponent leży na paintbox'ie. I jeszcze jedno: jak w delphi otrzymać zrzut ekranu, a potem wydrukować go na drukarce?

edytowany 1x, ostatnio: furious programming, 2018-02-11 15:56

Pozostało 580 znaków

2018-02-11 16:01
1
Romlus napisał(a):

Mam na formie paintbox na którym użytkownik rysuje linie. Potrzebuję jakiejś przezroczystej kontrolki (może to być panel lub Timage lub inna) na którą nakładam siatkę linii, a cały komponent leży na paintbox'ie.

Nie. Absolutnie nie.

Funkcja malowania linii oraz tła powinna być zrealizowana w tym samym komponencie. Utwórz w pamięci bitmapę pomocniczą (back buffer), na tej bitmapie maluj to co chce użytkownik. W zdarzeniu PaintBox.OnPaint najpierw namaluj zawartość pomocniczej bitmapy, a następnie na wierzchu siatkę linii.

Nie dość, że ograniczysz się do jednego komponentu, to samo malowanie i renderowanie kontrolki będzie dużo szybsze.

I jeszcze jedno: jak w delphi otrzymać zrzut ekranu, a potem wydrukować go na drukarce?

Jak zrobić zrzut z ekranu


edytowany 2x, ostatnio: furious programming, 2018-02-11 16:05

Pozostało 580 znaków

2018-02-11 17:26
0

Możesz napisać więcej na ten temat? Chodzi mi o to że użytkownik rysuje ściany, czyli linie na paintbox'ie, a potem nakłada na ten obraz siatkę którą ma mieć możliwość przesuwać aż ustali odpowiednie położenie i wydrukuje całość.

Pozostało 580 znaków

2018-02-11 17:45
0

Tu nie ma co wyjaśniać – sposób jest zbyt prosty. :]

Potrzebujesz pomocniczej bitmapy, o takim samym rozmiarze co PaintBox. Wszystko co może malować użytkownik (czyli linie) malujesz na tej pomocniczej bitmapie, nie w OnPaint komponentu. Dzięki temu zawsze będziesz miał dostęp do surowego rysunku. W zdarzeniu PaintBox.OnPaint malujesz na płótnie kontrolki zawartość tej pomocniczej bitmapy, a następnie – również na płótnie komponentu – malujesz tę dodatkową siatkę.

Dzięki temu użytkownik na ekranie będzie widział swój rysunek wraz z siatką, a Ty będziesz posiadał w pamięci sam surowy rysunek. To pozwoli dowolnie przesuwać siatkę, bo jest malowana dynamicznie (czyli jest tworem wirtualnym).

Najlepiej by było napisać do tego celu własną, prostą kontrolkę i umieścić pomocniczą bitmapę wewnątrz niej (w sekcji private). Tworzyć ją w konstruktorze komponentu, zwalniać w destruktorze, zmieniać rozmiar np. w SetBounds i dać do niej dostęp za pomocą dodatkowej właściwości. Również całą funkcjonalność dotyczącą malowania (czyli ustawień stylu linii, klikania itd.) też należy umieścić w kodzie kontrolki. Dopisać sobie metody przetwarzające odpowiednie komunikaty (np. WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE) i zaimplementować w nich rysowanie.


edytowany 5x, ostatnio: furious programming, 2018-02-11 17:50

Pozostało 580 znaków

2018-02-11 18:07
0

W jaki sposób rysować w czasie rzeczywistym po bitmapie.

Tworzę bitmapę:

bitmapa:=TBitmap.Create;
bitmapa.Width:=paintbox1.Width;
bitmapa.Height:=paintbox1.Height;

Potem rysuję na płótnie:

bitmapa.canvas.Pen.Color:=clblack;
bitmapa.canvas.MoveTo(x1,y1);
bitmapa.canvas.LineTo(x3,y3);

Lecz efektu nie widać.

edytowany 1x, ostatnio: furious programming, 2018-02-11 18:14

Pozostało 580 znaków

2018-02-11 18:14
var
  BackBuffer: TBitmap;
begin
  BackBuffer := TBitmap.Create();
  BackBuffer.PixelFormat := pf24bit;
  BackBuffer.Width := PaintBox1.Width;
  BackBuffer.Height := PaintBox1.Height;

A zdarzenie OnPaint? Nie dziw się że nie widać nic na ekranie.

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  Self.Canvas.Draw(0, 0, BackBuffer);
end;

Zapomniałeś też o wypełnieniu tła pomocniczej bitmapy. Domyślnie – jeśli pamięć mnie nie myli – będzie czarne.

BackBuffer.Canvas.Brush.Color := clWhite;
BackBuffer.Canvas.FillRect(BackBuffer.Canvas.ClipRect);

edytowany 2x, ostatnio: furious programming, 2018-02-11 18:17

Pozostało 580 znaków

2018-02-12 08:48
0

Jak rozumiem, użytkownik w czasie działania programu rysuje na bitmapie w zdarzeniu paintbox.onmousemove?

Pozostało 580 znaków

2018-02-12 18:18
0

Nie wiem czy w swoim programie masz już zaimplementowaną obsługę myszy i ogólnie całego mechanizmu malowania, ale jeśli tak, to jedyne co musisz zrobić to wymienić wszystkie linijki malujące po PaintBox.Canvas na te malujące po BackBuffer.Canvas.

To spowoduje, że wszystko co namaluje użytkownik, znajdzie się na pomocniczej bitmapie (a nie na ekranie), więc po namalowaniu czegokolwiek na bitmapie, wywołaj PaintBox.Invalidate – ta metoda wywoła m.in. zdarzenie OnPaint, dzięki czemu kontrolka na ekranie zostanie odmalowana.


To pozwoli również na podgląd rozciągania linii podczas malowania. Przykładowo, w OnMouseDown zapamiętujesz współrzędne kliknięcia i ustawiasz flagę włączającą tryb malowania linii (zwykła zmienna logiczna), w OnMouseMove, jeśli ta flaga jest ustawiona, zapamiętujesz bieżące współrzędne kursora i wołasz Invalidate, a w OnPaint (jeśli flaga jest ustawiona) malujesz zawartość bitmapy na ekranie, następnie na podstawie zapamiętanych współrzędnych malujesz dynamicznie linię, a na koniec również dynamicznie malujesz siatkę na samej górze.

Zaraz coś naskrobię – tak będzie najłatwiej. ;)


edytowany 1x, ostatnio: furious programming, 2018-02-12 18:24
PS: z tym zaraz to się pospieszyłem – powinienem napisać „jak znajdę chwilę”. :D - furious programming 2018-02-13 01:40

Pozostało 580 znaków

2018-02-13 22:50
2

@Romlus: znalazłem chwilkę i wystrugałem małego PoC-a.

Nie wiem dokładnie jak to u Ciebie wygląda z tą siatką i liniami, więc dla testu napisałem apkę, w której użytkownik może malować prostokąty. Edytor posiada tylny bufor, na którym lądują dane naniesione przez użytkownika. W edytorze (na buforze nie) malowana jest też siatka na wierzchu. Podczas malowania prostokąta, widoczny jest w edytorze jego podgląd, a po puszczeniu klawisza myszy, ląduje w buforze.

Lewym przyciskiem myszy maluje się prostokąty (w taki sam sposób jak w zwykłym edytorze graficznym), a prawy przycisk służy do przesuwania siatki linii. Po lewej w oknie jest pole edytora, po prawej podgląd tego co znajduje się aktualnie w buforze.

Tutaj zrzut z działania: PaintBox PoC.webm

W razie gdybyś mial Lazarusa to również dołączam źródła w załączniku. Have fun. ;)


Pozostało 580 znaków

2018-02-14 12:09
0

Dzięki za pomoc. Mój program działa właściwie.

edytowany 1x, ostatnio: Romlus, 2018-02-14 12:09

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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