如何将Image控件上的Jpeg图象旋转90度?(200分)

  • 主题发起人 主题发起人 qj_chen
  • 开始时间 开始时间
// Image1中为原图,Image2显示旋转后的图
procedure TForm1.BitBtn1Click(Sender: TObject);
var
I, J: Integer;
BmpS, BmpD: TBitmap;
begin
BmpS := TBitmap.Create;
BmpD := TBitmap.Create;
BmpS.Assign(Image1.Picture.Graphic);
BmpD.Height := Image1.Picture.Width;
BmpD.Width := Image1.Picture.Height;
for I := 0 to Image1.Height do
for J := 0 to Image1.Width do
BmpD.Canvas.Pixels[(-I + Image1.Height), J] := BmpS.Canvas.Pixels[J, I];
Image2.Picture.Bitmap.Assign(BmpD);
end;
 
刚才是顺时针转了90度,若是逆时针转90度即顺时针270度,则将倒数第二句改为:
BmpD.Canvas.Pixels[I, Image1.Width - J] := BmpS.Canvas.Pixels[J, I];

事实上,顺时针转过A度后,新(Xx, Yx)旧(Xj, Yj)坐标的关系是:
Xx = Xj*cosA - Yj*sinA
Yx = Xj*sinA + Yj*cosA
 
To xWolf:
用 ScanLine 吧,这样太慢了!
To qj_chen:
为什么一定要是 Jpeg 呢?
要不然……
 
Xwolf:吸取教训了,答得很快嘛!还记得我借花献佛吗?
 
同Big_Z ,用ScanLine
 
我也来一次借花献佛吧,以下用的是ScanLine

FROM: Another_eYes 时间:99-10-17 22:03:40 ID:142971
sorry, 我以为你不要用delphi自带的控件呢.
下面代码是我把fastlib中的smoothrotate改成直接操作TBitmap的.

type
TFColor = record
b, g, r: byte;
end;
PFColor = ^TFColor;


function TrimInt(value, min, max: Integer): Integer;
begin
result := value;
if result < min then result := min
else if result > max then result := max;
end;

procedure SmoothRotate(Bmp,Dst:TBitmap;cx,cy:Integer;Angle:Extended);
var
Top,Bottom,Left,Right,eww,nsw,fx,fy,wx,wy: Extended;
cAngle,sAngle: Double;
xDiff,yDiff,ifx,ify,px,py,ix,iy,x,y: Integer;
nw,ne,sw,se, Tmp: PFColor;
begin
if not assigned(bmp) or not assigned(dst) then exit;
bmp.pixelformat := pf24bit;
dst.pixelformat := pf24bit; // only work with 24-bit bitmap
// if u can sure they r all 24-bit, u can
// delete these 2 lines
Angle:=-Angle*Pi/180;
sAngle:=Sin(Angle);
cAngle:=Cos(Angle);
xDiff:=(Dst.Width-Bmp.Width)div 2;
yDiff:=(Dst.Height-Bmp.Height)div 2;
for y:=0 to Dst.Height-1 do
begin
tmp := dst.scanline[y];
py:=2*(y-cy)+1;
for x:=0 to Dst.Width-1 do
begin
px:=2*(x-cx)+1;
fx:=(((px*cAngle-py*sAngle)-1)/ 2+cx)-xDiff;
fy:=(((px*sAngle+py*cAngle)-1)/ 2+cy)-yDiff;
ifx:=Round(fx);
ify:=Round(fy);

if(ifx > -1)and(ifx < Bmp.Width)and(ify > -1)and(ify < Bmp.Height) then
begin
eww:=fx-ifx;
nsw:=fy-ify;
iy:=TrimInt(ify+1,0,Bmp.Height-1);
ix:=TrimInt(ifx+1,0,Bmp.Width-1);
nw := pointer(integer(bmp.scanline[ify])+ifx*3);
ne := pointer(integer(bmp.scanline[ify])+ix*3);
sw := pointer(integer(bmp.scanline[iy])+ifx*3);
se := pointer(integer(bmp.scanline[iy])+ix*3);

Top:=nw^.b+eww*(ne^.b-nw^.b);
Bottom:=sw^.b+eww*(se^.b-sw.b);
Tmp^.b:=(Round(Top+nsw*(Bottom-Top))) and $ff;

Top:=nw^.g+eww*(ne^.g-nw^.g);
Bottom:=sw^.g+eww*(se^.g-sw^.g);
Tmp^.g:=(Round(Top+nsw*(Bottom-Top))) and $ff;

Top:=nw^.r+eww*(ne^.r-nw^.r);
Bottom:=sw^.r+eww*(se^.r-sw^.r);
Tmp^.r:=(Round(Top+nsw*(Bottom-Top))) and $ff;
end;
tmp := pointer(integer(tmp)+3);
end;
end;
end;

 
多人接受答案了。
 

Similar threads

后退
顶部