gradient z czterech kolorow

0

mam sobie cztery kolory o zakresu od 0 do 255.
kazdy kolor lezy na skrajnych punktach tego obrazu. jak teraz wyliczyc kolor pozostalych punktow obrazu, aby przeciscie kolorow bylo plynne? znaczy zeby powstal taki gradient.

0

Huh?! Jak byś chciał żeby to wyglądało? Możesz takie coś stworzyć w photoshopie? Jeżeli Ci się uda to analogicznie to zaprogramuj.

Ja bym to widział w ten sposób: Obraz dzielisz po przekątnych na 4 części w kształcie takich kawałków tortu :P następnie robisz w każdej części wypełnienie między dwoma kolorami. Dla uproszczenia robisz coś takiego, że w środku obraz jest ciemniejszy/jaśniejszy aby ukryć brak przejść między kolorami w środku.

Obrazek robiony na szybko w GIMPie więc traktuj to jako schemat tylko, a nie efekt końcowy :P
user image

0

Obraz dzielisz po przekątnych na 4 części w kształcie takich kawałków tortu

Prościej chyba będzie zrobić to scanline'ami, odpowiednio skalując kolor w poziomie i pionie.

0

dobra, moze inaczej. nie chce generowac obrazu. potrzebuje funkcji, ktora bedzie przyjmowac 8 parametrow:
2, to wymiary obrazu/tablicy dwuwymiarowej
kolejne 2 x,y wybranego punktu
pozostale 4, to te wartosci tych kolorow

0

No to robisz to analogicznie: obliczasz początkowy i końcowy kolor dla pozycji y, a później w ten sam sposób obliczasz to dla wartości x.

0
AB = (1-x/w)*A + (x/w)*B
CD = (1-x/w)*C + (x/w)*D
ABCD = (1-y/h)*AB + (y/h)*CD
ABCD = (1-y/h)(1-x/w)*A + (1-y/h)(x/w)*B + (y/h)(1-x/w)*C + (y/h)(x/w)*D

X = x/w
Y = y/h
ABCD = (1-Y)(1-X)*A + (1-Y)(X)*B + (Y)(1-X)*C + (Y)(X)*D

gdzie:
A - składowa koloru lewego górnego piksela
B - składowa koloru prawego górnego piksela
C - składowa koloru lewego dolnego piksela
D - składowa koloru prawego dolnego piksela
(x,y) - położenie szukanego piksela
(w,h) - wymiary obrazka
x/w = X - położenie szukanego piksela względem obrazka w osi x [0 - 1]
y/h = Y - położenie szukanego piksela względem obrazka w osi y [0 - 1]

Dopisane:

Po prostu szukany kolor jest dwuwymiarową średnią ważoną (wagami są odpowiednio X oraz Y) między pikselami narożnymi. AB to kolor średni ważony w osi X dla Y=0, CD to kolor średni ważony w osi X dla Y=1. ABCD to kolor ważony między AB a CD w osi Y. Warto zauważyć, że zamiana kolejności i tworzenie średniej ważonej w osi X między AC oraz BD da identyczny efekt.

0

Miałem trochę czasu i napisałem kodzik ale widzę, że już Szczawik mnie uprzedził :P

procedure TForm1.Gradient(Col1, Col2, Col3, Col4: TColor; Bmp: TBitmap);
type
  PixArray = array [1..3] of Byte;
var
  h, w: Integer;
  X, Y: Real;
  p: ^PixArray;
begin
  bmp.PixelFormat := pf24Bit;

  for h := 0 to bmp.Height - 1 do
  begin
    p := bmp.ScanLine[h];
    for w := 0 to bmp.Width - 1 do
    begin
      X:= w / bmp.Width;
      Y:= h / bmp.Height;
      p^[1] := Round(GetBvalue(Col1)*(1-X)*(1-Y)) + Round(GetBvalue(Col2)*X*(1-Y)) + Round(GetBvalue(Col3)*(1-X)*Y) + Round(GetBvalue(Col4)*X*Y);
      p^[2] := Round(GetGvalue(Col1)*(1-X)*(1-Y)) + Round(GetGvalue(Col2)*X*(1-Y)) + Round(GetGvalue(Col3)*(1-X)*Y) + Round(GetGvalue(Col4)*X*Y);
      p^[3] := Round(GetRvalue(Col1)*(1-X)*(1-Y)) + Round(GetRvalue(Col2)*X*(1-Y)) + Round(GetRvalue(Col3)*(1-X)*Y) + Round(GetRvalue(Col4)*X*Y);
      Inc(p);
    end;
  end;
end;

procedure TForm1.ColorValue(Col1, Col2, Col3, Col4, Wynik: TColor; X, Y, Width, Height: Integer);
var
  W, H: Real;
begin
  W:= X / Width;
  H:= Y / Height;
  Wynik:= RGB(Round(GetBvalue(Col1)*(1-W)*(1-H)) + Round(GetBvalue(Col2)*X*(1-Y)) + Round(GetBvalue(Col3)*(1-X)*Y) + Round(GetBvalue(Col4)*X*Y),
              Round(GetGvalue(Col1)*(1-W)*(1-H)) + Round(GetGvalue(Col2)*X*(1-Y)) + Round(GetGvalue(Col3)*(1-X)*Y) + Round(GetGvalue(Col4)*X*Y),
              Round(GetRvalue(Col1)*(1-W)*(1-H)) + Round(GetRvalue(Col2)*X*(1-Y)) + Round(GetRvalue(Col3)*(1-X)*Y) + Round(GetRvalue(Col4)*X*Y));
end;

oraz efekt działania procedury Gradient:
user image

/edit: procedura ColorValue dla podanych kolorów ustala kolor pixela Wynik na pozycji X,Y dla bitmapy o wielkości Width, Height.

0

oo! dzieki bardzo. o to mi chodzilo

0

Tylko teraz tak patrzę i stwierdzam, że niepotrzebnie to rozbijałem na RGB ;) Można z 3 linijek zrobić jedną.

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