artykuły

Delphi - Transformacje grafiki - Przezroczystość

21:36
Sun, 9 January 2005
Artykuł pokazuje jak uzyskać efekt przeźroczystości (nakładania się na siebie) dwóch obrazów.

Wstęp

Tak jak obiecałem, zajmiemy się dzisiaj nakładaniem obrazków. Spróbujemy nałożyć na siebie dwa obrazki, w sposób, aby oba były jednocześnie widoczne. Użyjemy przezroczystości. A przezroczystość to przecież nic innego jak średnia kolorów danych pikseli z obu obrazków. Kod tego efektu jest przejrzysty i krótki, a efekt zadziwiający. To jest właśnie szczególna cecha efektów graficznych. Niewielkim nakładem pracy możemy stworzyć ciekawe filtry.
Cóż, nie pozostaje mi nic innego jak zacząć - a więc - do dzieła! ;)

Piszemy program

  1. Przygotuj dwa obrazki (nazwij je "obrazek1.bmp" i "obrazek2.bmp" i umieść na dysku C: ). Możesz nazwać je inaczej, ale będziesz to musiał uwzględnić również w kodzie programu (zmienić ścieżkę).
  2. Na formularzu umieść przycisk (paleta Standard).
  3. Kliknij dwukrotnie na przycisk. Zostaniesz przeniesiony do edytora kodu.
  4. Do listy uses dodaj słówkoMath.
  5. Wygenerowaną przed chwilą procedurę uzupełnij następująco: procedure TForm1.Button1Click(Sender: TObject); var bitmapa1, bitmapa2, bitmapa3 : TBitmap; x, y : integer; r1, g1, b1: byte; r2, g2, b2: byte; kolor : TColor; kolor_sredni : TColor; begin // Utworzenie bitmap (bitmapy 1 i 2 to bitmapy wejściowe, a bitmapa 3 jest bitmapą wyjściową (przetworzoną)) bitmapa1 := TBitmap.Create; bitmapa2 := TBitmap.Create; bitmapa3 := TBitmap.Create; // Wczytanie obrazków bitmapa1.LoadFromFile('C:\obrazek1.bmp'); bitmapa2.LoadFromFile('C:\obrazek2.bmp'); // Bitmapa wyjściowa (bitmapa3) powinna mieć rozmiary takie jak większy z obrazków. bitmapa3.Width := Max(bitmapa1.Width, bitmapa2.Width); bitmapa3.Height := Max(bitmapa1.Height, bitmapa2.Height); // Pętla która "przejeżdża" nam po wierszach for y:=0 to bitmapa3.Height-1 do // Pętla która "przejeżdża" nam po pikselach danego wiersza for x:=0 to bitmapa3.Width-1 do begin // Pobieramy kolor aktualnego piksela, z aktualnego wiersza obrazka1 kolor := bitmapa1.Canvas.Pixels[x,y]; // Rozkładamy pobrany kolor na składowe (r-czerwony, g-zielony, b-niebieski) r1 := GetRValue(kolor); g1 := GetGValue(kolor); b1 := GetBValue(kolor); // Pobieramy kolor aktualnego piksela, z aktualnego wiersza obrazka2 kolor := bitmapa2.Canvas.Pixels[x,y]; // Rozkładamy pobrany kolor na składowe (r-czerwony, g-zielony, b-niebieski) r2 := GetRValue(kolor); g2 := GetGValue(kolor); b2 := GetBValue(kolor); // Oblicz średnią kolorów danych pikseli z obu obrazków (składowa1 + składowa2)/2 kolor_sredni := RGB( (r1+r2) div 2, (g1+g2) div 2, (b1+b2) div 2 ); // Narysuj piksel o obliczonym kolorze średnim na bitmapie wyjściowej bitmapa3.Canvas.Pixels[x,y] := kolor_sredni; end; // Po ukończeniu, wyświetl wynik (bitmapę wyjściową) na formie Form1.Canvas.Draw(0, 0, bitmapa3); end; Nie przejmuj się długością kodu, bo jego większość zajmują komentarze ;) Kod nie jest trudny i jeśli się wczytasz - zrozumiesz zasadę działania. Wiecie po co był nam potrzebny moduł Math ? Bez niego nie zadziałała by funkcja MAX, która z dwóch podanych na wejście liczb zwraca tą większą. Analogicznie istnieje również funkcja MIN, która z dwóch podanych na wejście liczb zwróci tą mniejszą (to tak na marginesie ;). Funkcję MAX można było oczywiście zapisać w postaci warunków, ale wiecie - lenistwo ;) Zmienną "bitmapa3" musimy powiększyć do rozmiarów większego obrazka (z tych dwóch załadowanych). Jeślibyśmy tego nie zrobili, wówczas mogłoby się zdarzyć, że pętla przechodziłaby przez nieistniejące piksele obrazka wyjściowego. Mniejsza z tym. W pętli najpierw pobieramy kolor danego piksela (na którym właśnie stoi pętla) z pierwszego obrazka, potem "rozbieramy" ;) go na 3 składowe. Następnie pobieramy kolor danego piksela z drugiego obrazka (również go rozkładamy na składowe). Obliczamy średnią składowych składających się na kolor. Średnią obliczamy w ten sposób iż bierzemy np. 5 liczb, dodajemy je do siebie i wynik dzielimy przez ilość liczb (czyli przez 5). Tutaj sytuacja jest podobna. Składową z pierwszego obrazka dodajemy do składowej z drugiego obrazka i dzielimy przez ilość dodanych składowych (czyli 2). Takie małe przypomnienie.
    Kolejnym krokiem jest narysowanie piksela w wybranym miejscu na bitmapie wyjściowej (bitmapa3) o obliczonym kolorze średnim.
    Do tej pory wszystko odbywało się w pamięci (nawet rysowanie) (tak jest najwydajniej). Gdy pętla jednak zakończy działanie, wówczas następuje wyświetlenie bitmapy na formie przy pomocy procedury Draw().

Zakończenie

Na koniec pozostało mi życzyć Wam Wesołych Świąt i szczęśliwego Nowego Roku. Jak zwykle do artykułu dołączam kod źródłowy omawianego dziś efektu. Dzięki za poświeconą uwagę! Kod źródłowy, dołączony do artykułu znajdziecie w tym miejscu.

12345
Delphi - Transformacje grafiki - Przezroczystość Autor opinii: Czytelnicy, data przesłania: 0

Podobne artykuly:

Skomentuj

Aby zamieścić komentarz, proszę włączyć JavaScript - niestety roboty spamujące dają mi niezmiernie popalić.






Komentarze czytelników

    • Niko
    • Wed, 3 July 2013, 20:20
    • W lazarusie nie chce działać
      niewiem czemu ?
    • TomRiddle
    • Fri, 17 September 2010, 13:39
    • Można ten kod przerobić tak, żeby forma była przeźroczysta, dzięki:
      Transparent := True;
      TransparentColor := clSkyBlue;
      Color := clSkyBlue

      I żeby ta bitmapa pobierała obraz z pulpitu??
Dexter