123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- { TFPCustomInterpolation }
- procedure TFPCustomInterpolation.Initialize(aimage: TFPCustomImage; acanvas: TFPCustomCanvas);
- begin
- fimage := aimage;
- fcanvas := acanvas;
- end;
- { TFPBaseInterpolation }
- type
- TInterpolationContribution = record
- weight : double;
- place : integer;
- end;
- function ColorRound (c : double) : word;
- begin
- if c > $FFFF then
- result := $FFFF
- else if c < 0.0 then
- result := 0
- else
- result := round(c);
- end;
- procedure TFPBaseInterpolation.Horizontal (width : integer);
- var x,y,r : integer;
- start, stop, maxcontribs : integer;
- center, re,gr,bl, density : double;
- contributions : array[0..10] of TInterpolationContribution;
- dif, w, gamma, a : double;
- c : TFPColor;
- begin
- for x := 0 to width-1 do
- begin
- center := x * xfactor;
- start := round (center-xsupport);
- if start < 0 then
- start := 0;
- stop := round(center+xsupport);
- if stop >= image.Width then
- stop := image.Width-1;
- density := 0.0;
- maxcontribs := -1;
- for r := start to stop do
- begin
- dif := r - center;
- w := Filter (dif);
- if w > 0.0 then
- begin
- inc (maxcontribs);
- with contributions[maxcontribs] do
- begin
- weight := w;
- density := density + w;
- place := r;
- end;
- end;
- end;
- if (density <> 0.0) and (density <> 1.0) then
- begin
- density := 1.0 / density;
- for r := 0 to maxcontribs do
- contributions[r].weight := contributions[r].weight * density;
- end;
- for y := 0 to image.height-1 do
- begin
- gamma := 0.0;
- re := 0.0;
- gr := 0.0;
- bl := 0.0;
- for r := 0 to maxcontribs do
- with contributions[r] do
- with image.colors[place,y] do
- begin
- a := weight * alpha / $FFFF;
- re := re + a * image.colors[place,y].red;
- gr := gr + a * image.colors[place,y].green;
- bl := bl + a * image.colors[place,y].blue;
- gamma := gamma + a;
- end;
- with c do
- begin
- red := ColorRound (re);
- green := ColorRound (gr);
- blue := ColorRound (bl);
- alpha := ColorRound (gamma * $FFFF) ;
- end;
- tempimage.colors[x,y] := c;
- end;
- end;
- end;
- procedure TFPBaseInterpolation.vertical(dx,dy,width,height: integer);
- var x,y,r : integer;
- start, stop, maxcontribs : integer;
- center, re,gr,bl, density : double;
- contributions : array[0..10] of TInterpolationContribution;
- dif, w, gamma, a : double;
- c : TFPColor;
- begin
- for y := 0 to height-1 do
- begin
- center := y * yfactor;
- start := round (center-ysupport);
- if start < 0 then
- start := 0;
- stop := round(center+ysupport);
- if stop >= tempimage.height then
- stop := tempimage.height-1;
- density := 0.0;
- maxcontribs := -1;
- for r := start to stop do
- begin
- dif := r - center;
- w := Filter (dif);
- if w > 0.0 then
- begin
- inc (maxcontribs);
- with contributions[maxcontribs] do
- begin
- weight := w;
- density := density + w;
- place := r;
- end;
- end;
- end;
- if (density <> 0.0) and (density <> 1.0) then
- begin
- density := 1.0 / density;
- for r := 0 to maxcontribs do
- contributions[r].weight := contributions[r].weight * density;
- end;
- for x := 0 to width-1 do
- begin
- gamma := 0.0;
- re := 0.0;
- gr := 0.0;
- bl := 0.0;
- for r := 0 to maxcontribs do
- with contributions[r] do
- with tempimage.colors[x,place] do
- begin
- a := weight * alpha / $FFFF;
- re := re + a * red;
- gr := gr + a * green;
- bl := bl + a * blue;
- gamma := gamma + a;
- end;
- with c do
- begin
- red := ColorRound (re);
- green := ColorRound (gr);
- blue := ColorRound (bl);
- alpha := ColorRound (gamma * $FFFF);
- end;
- canvas.colors[x+dx,y+dy] := c;
- end;
- end;
- end;
- procedure TFPBaseInterpolation.Execute(x, y, w, h: integer);
- var maxy : integer;
- rx,ry : integer;
- begin
- tempimage := TFPMemoryImage.Create (w,image.height);
- tempimage.UsePalette := false;
- xfactor := image.Width / w;
- yfactor := image.Height / h;
- if xfactor > 1.0 then
- xsupport := MaxSupport
- else
- xsupport := xfactor * MaxSupport;
- if yfactor > 1.0 then
- ysupport := MaxSupport
- else
- ysupport := yfactor * MaxSupport;
- Horizontal (w);
- Vertical (x,y,w,h);
- end;
- { TMitchelInterpolation }
- function TMitchelInterpolation.Filter(x: double): double;
- const
- B = (1.0/3.0);
- C = (1.0/3.0);
- P0 = (( 6.0- 2.0*B )/6.0);
- P2 = ((-18.0+12.0*B+ 6.0*C)/6.0);
- P3 = (( 12.0- 9.0*B- 6.0*C)/6.0);
- Q0 = (( 8.0*B+24.0*C)/6.0);
- Q1 = (( -12.0*B-48.0*C)/6.0);
- Q2 = (( 6.0*B+30.0*C)/6.0);
- Q3 = (( - 1.0*B- 6.0*C)/6.0);
- begin
- if (x < -2.0) then
- result := 0.0
- else if (x < -1.0) then
- result := Q0-x*(Q1-x*(Q2-x*Q3))
- else if (x < 0.0) then
- result := P0+x*x*(P2-x*P3)
- else if (x < 1.0) then
- result := P0+x*x*(P2+x*P3)
- else if (x < 2.0) then
- result := Q0+x*(Q1+x*(Q2+x*Q3))
- else
- result := 0.0;
- end;
- function TMitchelInterpolation.MaxSupport: double;
- begin
- result := 2.0;
- end;
|