| Uutiset | Koodikirjasto | Wiki | Keskustelut | FAQ | Info |
Gradient4Marko 30.07.05 18:05 Liukuvärjäys neljän eri värin välillä
// Ohjelmapätkää voisi nopeuttaa entisestään käyttämällä kokonaislukuja liukulukujen sijaan // vaikka tietokoneet ovatkin nykyisin aika tehokkaita procedure SplitToRGB(Color: TColor; var R, G, B: Byte); begin R := (Color and 255); G := (Color shr 8) and 255; B := (Color shr 16) and 255; end; function CombineRGB(r, g, b: Byte): TColor; begin Result := (b shl 16) + (g shl 8) + r; end; procedure Gradient4(var Bmp: TBitmap; clTopLeft, clTopRight, clBottomLeft, clBottomRight: TColor); const PixelCountMax = 32768; type pRGBTripleArray = ^TRGBTripleArray; TRGBTripleArray = array[0..PixelCountMax-1] of TRGBTriple; TRGB = record R, G, B: Byte; end; var Row: pRGBTripleArray; Width, Height, i, j: Integer; Start_R, Start_G, Start_B, Stop_R, Stop_G,Stop_B: Byte; rgbTopLeft, rgbTopRight, rgbBottomLeft, rgbBottomRight: TRGB; IncLeft_R, IncLeft_G, IncLeft_B, IncRight_R, IncRight_G, IncRight_B: Real; Left_R, Left_G, Left_B, Right_R, Right_G, Right_B: Real; DiffLeft_R, DiffLeft_G, DiffLeft_B, DiffRight_R, DiffRight_G, DiffRight_B: Integer; Diff_R, Diff_G, Diff_B: Integer; Inc_R, Inc_G, Inc_B: Real; R, G, B: Real; begin Width := Bmp.Width; // Bittikartan leveys Height := Bmp.Height; // Bittikartan korkeus Bmp.PixelFormat := pf24bit; // Laitetaan bittikartta 24-bittiseksi, muuten ei toimi // Erotellaan parameterinä annetut värit RGB-väreihin with rgbTopLeft do SplitToRGB(clTopLeft, r, g, b); with rgbTopRight do SplitToRGB(clTopRight, r, g, b); with rgbBottomLeft do SplitToRGB(clBottomLeft, r, g, b); with rgbBottomRight do SplitToRGB(clBottomRight, r, g, b); // Lasketaan "ala"- ja "ylä"-arvojen erot jokaiselle värikomponentille vasemmalle värille DiffLeft_R := rgbBottomLeft.R - rgbTopLeft.R; DiffLeft_G := rgbBottomLeft.G - rgbTopLeft.G; DiffLeft_B := rgbBottomLeft.B - rgbTopLeft.B; // Lasketaan "ala"- ja "ylä"-arvojen erot jokaiselle värikomponentille oikealle värille DiffRight_R := rgbBottomRight.R - rgbTopRight.R; DiffRight_G := rgbBottomRight.G - rgbTopRight.G; DiffRight_B := rgbBottomRight.B - rgbTopRight.B; // Lasketaan "stepsize" vasemmalle värille // Nämä arvot voivat olla negatiivisia IncLeft_R := DiffLeft_R / Height; IncLeft_G := DiffLeft_G / Height; IncLeft_B := DiffLeft_B / Height; // Lasketaan "stepsize" oikealle värille // Nämä arvot voivat olla negatiivisia IncRight_R := DiffRight_R / Height; IncRight_G := DiffRight_G / Height; IncRight_B := DiffRight_B / Height; // Aloitusvärikomponentit vasemmalle värille Left_R := RGBTopLeft.R; Left_G := RGBTopLeft.G; Left_B := RGBTopLeft.B; // Aloitusvärikomponentit oikealle värille Right_R := RGBTopRight.R; Right_G := RGBTopRight.G; Right_B := RGBTopRight.B; for j := 1 to Height do // Height on bittikartan korkeus pikseleissä begin // Erotellaan vasen väri RGB-värikomponentteihin SplitToRGB(CombineRGB(Trunc(Left_R), Trunc(Left_G), Trunc(Left_B)), Start_R, Start_G, Start_B); // Erotellaan oikea väri RGB-värikomponentteihin SplitToRGB(CombineRGB(Trunc(Right_R), Trunc(Right_G), Trunc(Right_B)), Stop_R, Stop_G, Stop_B); // Lasketaan erot loppu- ja alkuvärien kesken Diff_R := Stop_R - Start_R; Diff_G := Stop_G - Start_G; Diff_B := Stop_B - Start_B; // Lasketaan loppu- ja alkuvärien "stepsize" jokaiselle värikomponentille. // Width-muuttuja on bittikartan leveys pikseleissä Inc_R := Diff_R / Width; Inc_G := Diff_G / Width; Inc_B := Diff_B / Width; // Annetaan aloitusarvot muuttujille R, G, B // Näitä muuttujia käytetään kun lasketaan horisontaaliset värit R := Start_R; G := Start_G; B := Start_B; // Valitaan rivi bitmapista Row := Bmp.Scanline[j - 1]; for i := 1 to Width do begin with Row[i - 1] do // Annetaan väri i - 1 pisteelly bittikartassa begin // Pyöristetään arvot tässä rgbtRed := Round(R); rgbtGreen := Round(G); rgbtBlue := Round(B); end; // Lisätään askelta R := R + Inc_R; G := G + Inc_G; B := B + Inc_B; end; // Vasemman värin komponentit // Arvo pienenee tai suurenee riippuen ovatko arvot negatiivisia vai positiivisia // IncLeft_.. arvot määriteltiin ennen for-silmukoita Left_R := Left_R + IncLeft_R; Left_G := Left_G + IncLeft_G; Left_B := Left_B + IncLeft_B; // Oikean värin komponentit // Tässä vastaava juttu kuin vasemmassa värissä Right_R := Right_R + IncRight_R; Right_G := Right_G + IncRight_G; Right_B := Right_B + IncRight_B; end; end; (* ....... ....... ....... ....... Näitä voi käyttää testaamiseen... procedure TForm1.FormPaint(Sender: TObject); var Bmp: TBitmap; begin Bmp := TBitmap.Create; Bmp.Width := Form1.Width; Bmp.Height := Form1.Height; Gradient4(Bmp, clRed, clPurple, clLime, clYellow); Form1.Canvas.Draw(0, 0, Bmp); Bmp.Free; end; procedure TForm1.FormResize(Sender: TObject); begin Form1.Repaint; end; *) jpdef 12:03 24.8.05 Ihan mukava. Ja jos tahtoo välttää jatkuvan uudelleen laskemisen tuossa testauksessa niin: procedure TForm1.FormPaint(Sender: TObject); begin Canvas.StretchDraw(ClientRect, Bmp); end; procedure TForm1.FormResize(Sender: TObject); begin Repaint; end; procedure TForm1.FormCreate(Sender: TObject); begin Bmp := TBitmap.Create; Bmp.Width := Screen.Width; Bmp.Height := Screen.Height; Gradient4(Bmp, clRed, clPurple, clLime, clYellow); end; |
![]() Haku
|