Programación General > Delphi

 Rotación De Imágenes En Delphi.

(1/1)

Amilius:
Adjunto una carta de respuesta conteniendo el código en el buen DELPHI para realizar rotación con antialisado. Si alguien consigue un componente para delphi o mejor un método para una clase heredada del Tbitmap sea bienvenido!!!.

Verán que el nivel de complejidad de la operación a nivel de pixel es elevado, un montón de multiplicaciones y saltos (if).  ;)


--- Código: Text --- From: Harm <harmans@uswest.net>Subject: Re: 2d rotaion trouble!Date: 28 Mar 1999 00:00:00 GMTMessage-ID: <36FE5D74.C74E566C@uswest.net>Content-Transfer-Encoding: 7bitReferences: <e5bL2.456$Xc6.578@news.get2net.dk>Content-Type: text/plain; charset=us-asciiX-Complaints-To: harmans@uswest.netNNTP-Posting-Date: Sun, 28 Mar 1999 10:48:22 CDTNewsgroups: comp.graphics.algorithms Here's Delphi pascal code to rotate an image any angle, with edge wrapping,and anti-aliasing.  Converted and added the edge wrapping, from original VBcode by Rod Stephens.  At least it wasn't (shudder) C++.  :) procedure TForm1.RotateAngle(Angle: integer);var  Theta, cosTheta, sinTheta: Single;    cx, cy                 : Single; //Center X, Y    sfrom_y, sfrom_x       : Single; //Real number    ifrom_y, ifrom_x       : Integer; //Integer version    to_y, to_x             : 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;    pb, pc : pRGBArray;begin  Screen.Cursor := crHourGlass;  CopyMe(ud,b);  //Copy to the undo bitmap  CopyMe(tBufr,b);  //Copy to the internal buffer bitmap    // Calculate the sine and cosine of theta for later.  Theta:=-(Angle)*Pi/180;  sinTheta:=Sin(Theta);  cosTheta:=Cos(Theta);  cx := b.Width / 2;  //Center of rotation for x  cy := b.Height / 2; //Center of rotation for y    // Perform the rotation.  for to_y := 0 to b.Height-1 do begin    for to_x := 0 to b.Width-1 do begin            // Find the location (from_x, from_y) that            // rotates to position (to_x, to_y).      sfrom_x := cx +          (to_x - cx) * cosTheta -          (to_y - cy) * sinTheta;      ifrom_x := Trunc(sfrom_x);       sfrom_y := cy +          (to_x - cx) * sinTheta +          (to_y - cy) * cosTheta;      ifrom_y := Trunc(sfrom_y);                 // Calculate the weights.      if sfrom_y >= 0  then begin        weight_y[1] := sfrom_y - ifrom_y;        weight_y[0] := 1 - weight_y[1];      end else begin        weight_y[0] := -(sfrom_y - ifrom_y);        weight_y[1] := 1 - weight_y[0];      end;      if sfrom_x >= 0 then begin        weight_x[1] := sfrom_x - ifrom_x;        weight_x[0] := 1 - weight_x[1];      end else begin        weight_x[0] := -(sfrom_x - ifrom_x);        Weight_x[1] := 1 - weight_x[0];      end;       if ifrom_x < 0 then        ifrom_x := b.Width -1-(-ifrom_x mod b.Width)      else if ifrom_x > b.Width-1  then        ifrom_x := ifrom_x mod b.Width;      if ifrom_y < 0 then        ifrom_y := b.Height -1-(-ifrom_y mod b.Height)      else if ifrom_y > b.Height-1 then        ifrom_y := ifrom_y mod b.Height;                 // Average the color components of the four                // nearest pixels in from_canvas.        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 ifrom_y + iy < b.Height then              pc := tBufr.ScanLine[ifrom_y + iy]            else              pc := tBufr.ScanLine[b.Height - ifrom_y - iy];            if ifrom_x + ix < b.Width then begin              new_red := pc[ifrom_x + ix].rgbtRed;              new_green := pc[ifrom_x + ix].rgbtGreen;              new_blue := pc[ifrom_x + ix].rgbtBlue;              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            else begin              new_red := pc[b.Width - ifrom_x - ix].rgbtRed;              new_green := pc[b.Width - ifrom_x - ix].rgbtGreen;              new_blue := pc[b.Width - ifrom_x - ix].rgbtBlue;              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;        end;        pb := b.ScanLine[to_y];        pb[to_x].rgbtRed := Round(total_red);        pb[to_x].rgbtGreen := Round(total_green);        pb[to_x].rgbtBlue := Round(total_blue);    end;  end;  imSine.Picture.Assign(b);  //all done, assign the bmp to our image  Screen.Cursor := crDefault;end;  morphix wrote: > I have some problems figuring how to do a 2d rotation on an image. The> resulting image has blank pixels (holes that isn't filled with color)> could anybody please show me an algorithm that works, (pascal, c, c++ or> pseudo)>> Morphix --Harmans Omaha NE  

Navegación

[0] Índice de Mensajes

Ir a la versión completa