Mega Code Archive

 
Categories / Delphi / Graphic
 

Gradient basics

Title: Gradient basics Question: How can I draw Gradients? Answer: Creating gradients can be the beauty part of your application. You can put then as background for forms, menus, buttons. One of the best library I have seen is Bi Library. It contain gradient buttons, background and many other cool UI components. In this article I want to demonstrate how easy is to create a gradient. A basic definition of a gradient is: "A gradient is a transition from one color to another". With this definition in mind we will start in creation of gradients. About colors For this project we will work with RGB "color model". Wha that means? Any pixel is represented as a record of three value: AColor= record Red:byte; Green:byte; Blue:byte; end; Maybe you know that. So let's undestand how gradients works. Suppose you want to create a gradient on a canvas C from a color, named Color_A to another color named Color_B. Only you have to do is to calculate for each RGB the difference between Color_A and Color_B and the intermediate color. For easy undestanding, I have groupped in a single unit many gradient types (many of then are not my original conception). Look at the source code and enjoy! {------------------------Code start here------------------------} unit rbgrdutils; interface uses Windows, Classes, Graphics, Forms, Controls, Dialogs; type TGradientFillType=(rgsHorizontal, rgsVertical, rgsElliptic, rgsRectangle, rgsVerticalCenter, rgsHorizontalCenter, rgsNWSE, rgsNWSW, rgsSENW,rgsSWNE, rgsSweet, rgsStrange, rgsNeo); procedure RbsGradientFill( Canvas:TCanvas; grdType:TGradientFillType; fromCol:TColor; toCol:TColor;ARect:TRect); implementation procedure RbsGradientFill( Canvas:TCanvas;grdType:TGradientFillType;fromCol:TColor; toCol:TColor;ARect:TRect); var FromR, FromG, FromB : Integer; DiffR, DiffG, DiffB : Integer; i: integer; bm:TBitmap; ColorRect:TRect; R,G,B:Byte; //for elliptical Pw, Ph : Real; x0,y0,x1,y1,x2,y2,x3,y3 : Real; points:array[0..3] of TPoint; haf:Integer; begin //set bitmap bm:=TBitmap.Create; bm.Width := ARect.Right; bm.Height := ARect.Bottom; //calc colors FromR := fromcol and $000000ff; //Strip out separate RGB values FromG := (fromcol shr 8) and $000000ff; FromB := (fromcol shr 16) and $000000ff; DiffR := (tocol and $000000ff) - FromR; //Find the difference DiffG := ((tocol shr 8) and $000000ff) - FromG; DiffB := ((tocol shr 16) and $000000ff) - FromB; //draw gradient case grdType of rgsHorizontal: begin ColorRect.Top:= 0; //Set rectangle top ColorRect.Bottom := bm.Height; for I := 0 to 255 do begin //Make lines (rectangles) of color ColorRect.Left:= MulDiv (I, bm.Width, 256); //Find left for this color ColorRect.Right:= MulDiv (I + 1, bm.Width, 256); //Find Right R := fromR + MulDiv(I, diffr, 255); //Find the RGB values G := fromG + MulDiv(I, diffg, 255); B := fromB + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush bm.Canvas.FillRect(ColorRect); //Draw on Bitmap end; end; rgsVertical: begin ColorRect.Left:= 0; //Set rectangle left&right ColorRect.Right:= bm.Width; for I := 0 to 255 do begin //Make lines (rectangles) of color ColorRect.Top:= MulDiv (I, bm.Height, 256); //Find top for this color ColorRect.Bottom:= MulDiv (I + 1, bm.Height, 256); //Find Bottom R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush bm.Canvas.FillRect(ColorRect); //Draw on Bitmap end; end; rgsElliptic: begin bm.Canvas.Pen.Style := psClear; bm.Canvas.Pen.Mode := pmCopy; x1 := 0 - (bm.Width / 4); x2 := bm.Width + (bm.Width / 4)+4; y1 := 0 - (bm.Height / 4); y2 := bm.Height + (bm.Height / 4)+4; Pw := ((bm.Width / 4) + (bm.Width / 2)) / 155; Ph := ((bm.Height / 4) + (bm.Height / 2)) / 155; for I := 0 to 155 do begin //Make ellipses of color x1 := x1 + Pw; x2 := X2 - Pw; y1 := y1 + Ph; y2 := y2 - Ph; R := fromr + MulDiv(I, diffr, 155); //Find the RGB values G := fromg + MulDiv(I, diffg, 155); B := fromb + MulDiv(I, diffb, 155); bm.Canvas.Brush.Color := R or (G shl 8) or (b shl 16); //Plug colors into brush bm.Canvas.Ellipse(Trunc(x1),Trunc(y1),Trunc(x2),Trunc(y2)); end; end; rgsRectangle: begin bm.Canvas.Pen.Style := psClear; bm.Canvas.Pen.Mode := pmCopy; x1 := 0; x2 := bm.Width+2; y1 := 0; y2 := bm.Height+2; Pw := (bm.Width / 2) / 255; Ph := (bm.Height / 2) / 255; for I := 0 to 255 do begin //Make rectangles of color x1 := x1 + Pw; x2 := X2 - Pw; y1 := y1 + Ph; y2 := y2 - Ph; R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush bm.Canvas.FillRect(Rect(Trunc(x1),Trunc(y1),Trunc(x2),Trunc(y2))); end; end; rgsVerticalCenter: begin Haf := bm.Height Div 2; ColorRect.Left := 0; ColorRect.Right := bm.Width; for I := 0 to Haf do begin ColorRect.Top := MulDiv (I, Haf, Haf); ColorRect.Bottom := MulDiv (I + 1, Haf, Haf); R := fromr + MulDiv(I, diffr, Haf); G := fromg + MulDiv(I, diffg, Haf); B := fromb + MulDiv(I, diffb, Haf); bm.Canvas.Brush.Color := RGB(R, G, B); bm.Canvas.FillRect(ColorRect); ColorRect.Top := bm.Height - (MulDiv (I, Haf, Haf)); ColorRect.Bottom := bm.Height - (MulDiv (I + 1, Haf, Haf)); bm.Canvas.FillRect(ColorRect); end; end; rgsHorizontalCenter: begin Haf := bm.Width Div 2; ColorRect.Top := 0; ColorRect.Bottom := bm.Height; for I := 0 to Haf do begin ColorRect.Left := MulDiv (I, Haf, Haf); ColorRect.Right := MulDiv (I + 1, Haf, Haf); R := fromr + MulDiv(I, diffr, Haf); G := fromg + MulDiv(I, diffg, Haf); B := fromb + MulDiv(I, diffb, Haf); bm.Canvas.Brush.Color := RGB(R, G, B); bm.Canvas.FillRect(ColorRect); ColorRect.Left := bm.Width - (MulDiv (I, Haf, Haf)); ColorRect.Right := bm.Width - (MulDiv (I + 1, Haf, Haf)); bm.Canvas.FillRect(ColorRect); end; end; rgsNWSE: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; Pw := (bm.Width+bm.height) / 255; for I := 0 to 254 do begin //Make trapeziums of color x0 := i*Pw; if (x0 begin y0:=x0-bm.width; x0:=bm.width-1; end; x1:=(i+1)*pw; if (x1 y1:=0; end else begin y1:=x1-bm.width; x1:=bm.width-1; end; y2:=i*pw; if (y2 begin x2:=y2-bm.height; y2:=bm.height-1; end; y3:=(i+1)*pw; if (y3 begin x3:=y3-bm.height; y3:=bm.height-1; end; R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush points[0]:=point(Trunc(x0),Trunc(y0)); points[1]:=point(Trunc(x1),Trunc(y1)); points[3]:=point(Trunc(x2),Trunc(y2)); points[2]:=point(Trunc(x3),Trunc(y3)); bm.canvas.polygon(points); end; end; rgsNWSW: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; Pw := (bm.width+bm.height) / 255; for I := 0 to 254 do begin //Make trapeziums of color y0 := i*Pw; if (y0 begin x0:=bm.width-1-(y0-bm.height); y0:=bm.height-1; end; y1:=(i+1)*pw; if (y1 begin x1:=bm.width-1; end; x2:=bm.width-1-(i*pw); if (x20) then y2:=0 else begin y2:=-x2; x2:=0; end; x3:=bm.width-1-((i+1)*pw); if (x30) then y3:=0 else begin y3:=-x3; x3:=0; end; R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush points[0]:=point(Trunc(x0),Trunc(y0)); points[1]:=point(Trunc(x1),Trunc(y1)); points[3]:=point(Trunc(x2),Trunc(y2)); points[2]:=point(Trunc(x3),Trunc(y3)); bm.canvas.polygon(points); end; end; rgsSENW: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; Pw := (bm.width+bm.height) / 255; for I := 0 to 254 do begin //Make trapeziums of color y0 := bm.height-1-(i*Pw); if (y00) then x0:=bm.width-1 else begin x0:=bm.width-1+y0; y0:=0; end; y1:=bm.height-1-((i+1)*pw); if (y10) then x1:=bm.width-1 else begin x1:=bm.width-1+y1; y1:=0; end; x2:=bm.width-1-(i*pw); if (x20) then y2:=bm.height-1 else begin y2:=bm.height-1+x2; x2:=0; end; x3:=bm.width-1-((i+1)*pw); if (x30) then y3:=bm.height-1 else begin y3:=bm.height-1+x3; x3:=0; end; R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush points[0]:=point(Trunc(x0),Trunc(y0)); points[1]:=point(Trunc(x1),Trunc(y1)); points[3]:=point(Trunc(x2),Trunc(y2)); points[2]:=point(Trunc(x3),Trunc(y3)); bm.canvas.polygon(points); end; end; rgsSWNE: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; Pw := (bm.width+bm.height) / 255; for I := 0 to 254 do begin //Make trapeziums of color y0 := bm.height-1-(i*Pw); if (y00) then x0:=0 else begin x0:=-y0; y0:=0; end; y1:=bm.height-1-((i+1)*pw); if (y10) then x1:=0 else begin x1:=-y1; y1:=0; end; x2:=(i*pw); if (x2 begin y2:=bm.height-1-(x2-bm.width); x2:=bm.width-1; end; x3:=(i+1)*pw; if (x3 begin y3:=bm.height-1-(x3-bm.width); x3:=bm.width-1; end; R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.canvas.Brush.Color := RGB(R, G, B); //Plug colors into brush points[0]:=point(Trunc(x0),Trunc(y0)); points[1]:=point(Trunc(x1),Trunc(y1)); points[3]:=point(Trunc(x2),Trunc(y2)); points[2]:=point(Trunc(x3),Trunc(y3)); bm.canvas.polygon(points); end; end; rgssweet: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; for i:=0 to 255 do begin x1:=muldiv(i,bm.Width,255); x2:=muldiv(i+1,bm.Width,255); y1:=muldiv(i,bm.Height,255); y2:=muldiv(i+1,bm.Height,255); R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color:=RGB(R,G,B); points[0]:=point(bm.Width div 2,bm.Height div 2); points[1]:=point(0,trunc(y1)); points[2]:=point(0,trunc(y2)); points[3]:=points[2]; bm.canvas.polygon(points); points[0]:=point(bm.Width div 2,bm.Height div 2); points[1]:=point(bm.Width,bm.Height-trunc(y1)); points[2]:=point(bm.Width,bm.Height-trunc(y2)); points[3]:=points[2]; bm.canvas.polygon(points); points[0]:=point(bm.Width div 2,bm.Height div 2); points[1]:=point(trunc(x1),0); points[2]:=point(trunc(x2),0); points[3]:=points[2]; bm.canvas.polygon(points); points[0]:=point(bm.Width div 2,bm.Height div 2); points[1]:=point(bm.Width-trunc(x1),bm.Height); points[2]:=point(bm.Width-trunc(x2),bm.Height); points[3]:=points[2]; bm.canvas.polygon(points); end; end; rgsStrange: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; for i:=0 to 255 do begin x1:=muldiv(i,bm.Width,255); y1:=muldiv(i,bm.Height,255); R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color:=RGB(R,G,B); points[0]:=point(trunc(x1),trunc(y1)); points[1]:=point(0,bm.Height-trunc(y1)); points[2]:=point(bm.Width,bm.Height); points[3]:=point(bm.width,0); bm.canvas.polygon(points); end; end; rgsNeo: begin bm.canvas.Pen.Style := psclear; bm.canvas.Pen.Mode := pmCopy; for i:=0 to 255 do begin x1:=muldiv(i,bm.Width div 2,255); y1:=muldiv(i,bm.Height div 2,255); R := fromr + MulDiv(I, diffr, 255); //Find the RGB values G := fromg + MulDiv(I, diffg, 255); B := fromb + MulDiv(I, diffb, 255); bm.Canvas.Brush.Color:=RGB(R,G,B); points[0]:=point(trunc(x1),trunc(y1)); points[1]:=point(0,bm.Height); points[2]:=point(bm.Width-trunc(x1),bm.Height-trunc(y1)); points[3]:=point(bm.width,0); bm.canvas.polygon(points); end; end; end; BitBlt(Canvas.Handle,0,0,bm.Width,bm.Height,bm.Canvas.Handle,0,0,SRCCOPY); //Canvas.CopyRect(arect,bm.Canvas,arect); bm.Free; end; end.