Skanowanie obrazka i zabawa kolorami

psychoszayber

Skanowanie obrazka i zabawa kolorami

Kolor składa się z trzech wartości:
*Red - Czerwony (wartości 0-255)
*Green - Zielony (wartości 0-255)
*Blue - Niebieski (wartości 0-255)

Stąd wzięła się nazwa RGB.

Z koloru można odzyskać wartość R, G lub B za pomocą funkcji

GetRValue

Można też stworzyć kolor za pomocą procedury

RGB(R,G,B);

gdzie R=red, G=green, B=blue.

Można manipulować kolorami np. dodać do wartości niebieskiej koloru 50 czyli kolor będzie miał wartość Blue o 50 większą.
Nic nie stoi na przeszkodzie więc żeby połączyć 2 obrazki i stworzyć z nich 3 obrazek.

Przykład procedury mieszającej dwa obrazki

Stwórz 3 obrazki, pierwsze 2 nazwij kolejno 'img1' i 'img2'; trzeci nazwij 'outer'

var
  R,G,B:byte;
  WI, HE: Integer;
begin
  for Wi := 0 to Img1.Picture.Width do //skanowanie obrazka -start
    for He := 0 to Img1.Picture.Height do
      begin
	R := GetRvalue(Img1.Canvas.Pixels[Wi, He]) + GetRvalue(Img2.Canvas.Pixels[Wi, He]); //dodawanie kolorów
	G := GetGvalue(Img1.Canvas.Pixels[Wi, He]) + GetGvalue(Img2.Canvas.Pixels[Wi, He]); // dodawanie kolorów
	B := GetBvalue(Img1.Canvas.Pixels[Wi, He]) + GetBvalue(Img2.Canvas.Pixels[Wi, He]); //dodawanie kolorów
	Outer.Canvas.Pixels[Wi, He] := RGB(R, G, B);// końcowe rysowanie wyliczonych kolorów w 3 obrazku
      end; //skanowanie obrazka -koniec
end;

Procedura ta wykonuje się dosyć długo ale przynosi niezły efekt. Można również xorować, odejmować, mnożyć, centrować ale nie można dzielić ( Centrować tzn. liczyć średną arytmetyczną z 2 liczb ). Można zastosować własne efekty matematyczne. Resztę zostawiam waszej wyobraźni. Najlepiej wychodzi xorowanie.

Ostatnia uwaga. Pierwszy obrazek musi być równy rozmiarem drugiemu lub większy, w przeciwnym wypadku po prostu 2 obrazek o tyle ile jest większy od 1 NIE będzie rysowany

7 komentarzy

można przecierz:

try
  R:=getRvalue(img1.canvas.pixels[wi,he]) div getRvalue(img2.canvas.pixels[wi,he]); 
g:=getgvalue(img1.canvas.pixels[wi,he]) div getgvalue(img2.canvas.pixels[wi,he]);         b:=getbvalue(img1.canvas.pixels[wi,he]) div getbvalue(img2.canvas.pixels[wi,he]); 
except
  on EDivByZero do
  begin
R:=(1+getRvalue(img1.canvas.pixels[wi,he])) div (1+getRvalue(img2.canvas.pixels[wi,he]); 
g:=(1+getgvalue(img1.canvas.pixels[wi,he])) div (1+getgvalue(img2.canvas.pixels[wi,he]);         b:=(1+getbvalue(img1.canvas.pixels[wi,he])) div (1+getbvalue(img2.canvas.pixels[wi,he]); 
  end;  
end;

u mnie dziala [DELPHI 7]

Nie to są tyko przykłady.

Dlatego sprawdzamy, czy nie jest równe 0 :) Mniejsza z tym. Coś mi się wydaje, że ten artykuł (a już na pewno ten drugi) to powinny w Gotowcach wylądować.

Mi by się przydało coś o zapełnianiu obszarów zamkniętych (bo FloodFill mi nie działa, jak zrobiłem procedurę rekurencyjną to przy obrazku 200x200 wywaliło StackOverflow...) i porównywaniu liczb z pewną tolerancją różnic (do porównywania kolorów).

Nie możemy dzielić poniwarz jest 98,8888(3)% na to że napotkamy na 0 i wtedy "AMEN".

Napiszę jeszcze inny artykuł o mieszanu obrazków.

Tylko przy takim dodawaniu, jeżeli mamy np. dwa piksele o wartościach obydwa 150 (czyli bardzo jasne), to uzyskamy w wyniku kolor 45, czyli dosyć ciemny. Lepsze chyba już jest or, bo przynajmniej nie przekroczy granicy.
I nie rozumiem, dlaczego nie możemy w takim razie dzielić. Musimy jedynie uważać, aby nie podzielić przez zero.
Poza tym, jest znacznie szybsza metoda takiego składania obrazków. Wystarczy ustawić odpowiedni tryb dla Pen oraz Brush i użyć CopyBrush, albo użyć funkcji Windowsowych *Blt

SPOX, chociaż moglo by być więcej przykładów ;)