Dynamiczne tworzenie bitmap

0

Jestem początkującym programistą.
Piszę (a właściwie próbuję napisać) program który miałby rysować wykresy. Z tym że:

  • nie odpowiada mi komponent TChart - bo tak
  • powiększenie lub zmniejszenie okna ma zmieniać rozmiar całego wykresu (jeżeli forma ma wymiary X na Y to obszar wykresu ma mieć (X-150)x(Y-150) itd.

Chcę teraz dorobić do tego jakiś zoom i przesuwanie po obszarze wykresu.

Algorytm ktory wykombinowałem wyglada mniej wiecej tak:

  1. Następuje zmiana rozmiaru formy -> proc. onResize tworzy w panelu image (mogłem wsadzić tam bitmape?) i rysuje na canvasie siatkę i osie o podziałce zależnej od rozmiaru (po uprzednim panel1.destroycomponents) - to działa dobrze i fajnie wygląda :)

  2. Ma nastąpić "wyprodukowanie" kilku bitmap (warstw) - o odpowiednim rozmiarze i dodanie jej ** do image ktora ma zawierac dane rysowane linia po linii.

Myślę że to może być bardzo uciążliwe dla procesora i pamięciożerne przy sporych rozdzielczościach. Czy macie jakieś pomysły jak to zrobić używając mniej zasobów? A może jeszcze jakieś inne wskazówki?

** jeszcze nie wiem jak - moze jakimś xor'em albo inną funkcją logiczną - pokombinuję

0

Bitmapę możesz tworzyć dynamicznie:

var BMP:TBitmap;
begin
BMP=:TBitmap.Create();
BMP.Width:=Szerokosc;
BMP.Hegiht:=Wysokosc;
BMP.Pixelformat:=pf24bit;
..
BMP.Free;
end;

Tu masz przykład mojego kodu do obróbki szybkiej kilku bitmap"
http://4programmers.net/Forum/viewtopic.php?id=86212

Warstwy sklejać możesz Canvas.CopyRect, z odpowiednio ustawionym CopyMode.

Renderuj wszystko na bitmapę w pamięci, przy zmianie rozmiaru renderuj na nowo, ale przy odświeżaniu tą bitmapę wklejaj na komponent (polecam TPaintBox).

0

Nie będzie zbyt obciążające dla procesora? To bedzie kilka bitmap o rozmiarze ok 5MB. Ja mam w miarę szybki procesor (1.7GHz) ale co bedzie jak odpalę to na powiedzmy notebooku 300MHz? (pomijając już ilość RAM'u).

0

Jak nie będziesz korzystał z Pixels[x,y] tylko ze ScanLine, będzie bardzo szybkie nawet na słabszych kompach, CopyRect rekordowo szybkie nie jest, ale jest zadowalające (a jak w oparciu o ScanLine napiszesz własną funkcję od razu sklejającą wszystkie warstwy, może być to o wiele szybsze). Oczywiście ma też znaczenie, ile zajmie samo rysowanie.

Po prostu sprawdź samemu. Napisz prosty programik, który skleja wiele warstw i puść na laptopie; będziesz wiedział, ile zajmuje renderowanie jednej klatki.

0

Problem w tym że do testów mam tylko swojego notebooka centrino 1.7 a program jest dedykowany również dla słabszego sprzętu. Nie pytał bym o to "co będzie jeżeli zrobię tak i tak" gdybym miał możliwość to sprawdzić. O co chodzi ze ScanLine? Będę wdzięczny za jakieś linki. Pozdrawiam.

0

jeśli rysunek składasz z lini (prostokąty, elipsy, z wypełnieniem i bez) czyli ogólnie sam rysujesz na podstawie jakichś danych (zazwyczaj tak powstają wykresy) a nie otwierasz pliku BMP i nie kopiujesz ich zawartości. To zamiast robić cuda niewidy napisz sobię procedurę, do której podajesz x i y lewego górnego rogu (chodzi o wsp. na wykresie a nie o położenie TImage czy TPaintBox), zoom i na tej podstawie narysuje Ci to co chcesz. Przykładowo masz obszar rysowania 301 x 301 pikseli, punkt 0, 0 jest na środku wykresu a zoom = 200%. Masz narysować linie z tablicy, która wygląda tak
tab: array[1..2] of array of TPoint;
to robisz tak:

Rysuj(-150, -150, 200)

a Rysuj wygląda tak

procedure Rysuj (x, y, zoom: integer);
begin
  for i := Low(tab) to High(tab) do
  begin
    MoveTo(Point((Trunc(tab[1, i].X + x) * zoom / 100), Trunc((tab[1, i].y - y) * zoom / 100)));
    LineTo(Point((Trunc(tab[2, i].X + x) * zoom / 100), Trunc((tab[2, i].y - y) * zoom / 100)));
  end;
end;

kod pisany z palca i może nie działać ale może ogólną ideę załapiesz :). Teraz przy przesuwaniu zmieniasz tylko x i y i masz inny kawałek wykresu

0

Nawet nie musisz tego skalować ręcznie - wystarczy użyć transformacji tego Canvas:
SetMapMode + SetWindowExt, itp. - i rysujemy zawsze jednakowo.
Albo nawet SetWorldTransform - można skalować, obracać... wszystko.

Przy okazji mamy załatwiony wydruk - a z TBitmap byłby problem (mapa bitowa dla drukarki (np. 600dpi, strona A4) miałaby chyba z 500MB! :D

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