首页  编辑  

图象扭曲算法

Tags: /超级猛料/Picture.图形图像编程/图形处理算法/   Date Created:

:卷起千堆雪tyn,

图象扭曲算法 :

procedure Twist(var Bmp, Dst: TBitmap; Amount: integer);

var

 fxmid, fymid : Single;

 txmid, tymid : Single;

 fx,fy : Single;

 tx2, ty2 : Single;

 r : Single;

 theta : Single;

 ifx, ify : integer;

 dx, dy : Single;

 OFFSET : Single;

 ty, tx             : Integer;

 weight_x, weight_y     : array[0..1] of Single;

 weight                 : Single;

 new_red, new_green     : Integer;

 new_blue               : Integer;

 total_red, total_green : Single;

 total_blue             : Single;

 ix, iy                 : Integer;

 sli, slo : PBytearray;

 function ArcTan2(xt,yt : Single): Single;

 begin

   if xt = 0 then

     if yt > 0 then

       Result := Pi/2

     else

       Result := -(Pi/2)

   else begin

     Result := ArcTan(yt/xt);

     if xt < 0 then

       Result := Pi + ArcTan(yt/xt);

   end;

 end;

begin

 OFFSET := -(Pi/2);

 dx := Bmp.Width - 1;

 dy := Bmp.Height - 1;

 r := Sqrt(dx * dx + dy * dy);

 tx2 := r;

 ty2 := r;

 txmid := (Bmp.Width-1)/2;    //Adjust these to move center of rotation

 tymid := (Bmp.Height-1)/2;   //Adjust these to move ......

 fxmid := (Bmp.Width-1)/2;

 fymid := (Bmp.Height-1)/2;

 if tx2 >= Bmp.Width then tx2 := Bmp.Width-1;

 if ty2 >= Bmp.Height then ty2 := Bmp.Height-1;

 for ty := 0 to Round(ty2) do begin

   for tx := 0 to Round(tx2) do begin

     dx := tx - txmid;

     dy := ty - tymid;

     r := Sqrt(dx * dx + dy * dy);

     if r = 0 then begin

       fx := 0;

       fy := 0;

     end

     else begin

       theta := ArcTan2(dx,dy) - r/Amount - OFFSET;

       fx := r * Cos(theta);

       fy := r * Sin(theta);

     end;

     fx := fx + fxmid;

     fy := fy + fymid;

     ify := Trunc(fy);

     ifx := Trunc(fx);

               // Calculate the weights.

     if fy >= 0  then begin

       weight_y[1] := fy - ify;

       weight_y[0] := 1 - weight_y[1];

     end else begin

       weight_y[0] := -(fy - ify);

       weight_y[1] := 1 - weight_y[0];

     end;

     if fx >= 0 then begin

       weight_x[1] := fx - ifx;

       weight_x[0] := 1 - weight_x[1];

     end else begin

       weight_x[0] := -(fx - ifx);

       Weight_x[1] := 1 - weight_x[0];

     end;

     if ifx < 0 then

       ifx := Bmp.Width-1-(-ifx mod Bmp.Width)

     else if ifx > Bmp.Width-1  then

       ifx := ifx mod Bmp.Width;

     if ify < 0 then

       ify := Bmp.Height-1-(-ify mod Bmp.Height)

     else if ify > Bmp.Height-1 then

       ify := ify mod Bmp.Height;

     total_red   := 0.0;

     total_green := 0.0;

     total_blue  := 0.0;

     for ix := 0 to 1 do begin

       for iy := 0 to 1 do begin

         if ify + iy < Bmp.Height then

           sli := Bmp.scanline[ify + iy]

         else

           sli := Bmp.scanline[Bmp.Height - ify - iy];

         if ifx + ix < Bmp.Width then begin

           new_red := sli[(ifx + ix)*3];

           new_green := sli[(ifx + ix)*3+1];

           new_blue := sli[(ifx + ix)*3+2];

         end

         else begin

           new_red := sli[(Bmp.Width - ifx - ix)*3];

           new_green := sli[(Bmp.Width - ifx - ix)*3+1];

           new_blue := sli[(Bmp.Width - ifx - ix)*3+2];

         end;

         weight := weight_x[ix] * weight_y[iy];

         total_red   := total_red   + new_red   * weight;

         total_green := total_green + new_green * weight;

         total_blue  := total_blue  + new_blue  * weight;

       end;

     end;

     slo := Dst.scanline[ty];

     slo[tx*3] := Round(total_red);

     slo[tx*3+1] := Round(total_green);

     slo[tx*3+2] := Round(total_blue);

   end;

 end;

end;

procedure Twist(var Bmp, Dst: TBitmap; Amount: integer);

这里的Bmp为源位图,Dst为目标位图,Amount为扭曲常数,你可以定义为任意整数,例如100.