任意角度围绕中心的位图旋转,相应的Image也要变化!不要借助控件!(100分)

  • 主题发起人 主题发起人 卷起千堆雪tyn
  • 开始时间 开始时间

卷起千堆雪tyn

Unregistered / Unconfirmed
GUEST, unregistred user!
我在帮你做:)
 
卷起千堆雪tyn大虾,你可别忘给分啊!!!!!!!!
(我做了这么久,还没吃晚饭呢!)
procedure RotateImage(Image: Timage; Angle: Integer; BColor: TColor);
{--------------------------------
x2 = x1*cos(a)-y1*sin(a)
y2 = x1*sin(a)+y1*cos(a)

x1 = x2*cos(a)+y2*sin(a)
y1 =-x2*sin(a)+y2*cos(a)

w2 = w1*cos(a)+h1*sin(a)
h2 = w1*sin(a)+h1*cos(a)
--------------------------------}
const
PI=3.1415926;
var
r1, c1: Integer;
r2, c2: Integer;//raw and col control variable
w1, h1: Integer;
w2, h2: Integer;//width and height variable
x1, y1: Double;
x2, y2: Double;//coordinate
cn, sn: Double;
Radian: Double;
Colour: TColor;
Bitmap: TBitmap;
begin
//Calculate radian
Radian := Angle/180*PI;
//Calculate cos(a) and sin(a)
cn := Cos(Radian);
sn := Sin(Radian);
w1 := Image.Width;
h1 := Image.Height;
//Calculate new height and new width
w2 := Round(Abs(w1*cn)+Abs(h1*sn));
h2 := Round(Abs(w1*sn)+Abs(h1*cn));
//Create a new bitmap
Bitmap := TBitmap.Create;
Bitmap.Width := w2;
Bitmap.Height := h2;
for r2 := 0 to h2-1 do
for c2 := 0 to w2-1 do
begin
x2 := c2 - w2/2;
y2 := r2 - h2/2;
x1 := x2*cn+y2*sn;
y1 :=-x2*sn+y2*cn;
c1 := Round(x1+w1/2);
r1 := Round(y1+h1/2);
if (c1>=0)and(c1<w1)and(r1>=0)and(r1<h1) then
Colour := Image.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
Bitmap.Canvas.Pixels[c2,r2] := Colour;
end;
Image.Picture.Bitmap := Bitmap;
Bitmap.Free;
end;
 
是不是来骗分的,
这个程序远不全的。
 
对不起,刚来看,发现没传完。
TO 称云:冤枉,我不是骗分的!!!
procedure RotateImage(Image: Timage; Angle: Integer; BColor: TColor);
const
PI=3.1415926;
var
r1, c1: Integer;
r2, c2: Integer;
w1, h1: Integer;
w2, h2: Integer;
x1, y1: Double;
x2, y2: Double;
cn, sn: Double;
Radian: Double;
Colour: TColor;
Bitmap: TBitmap;
begin
Radian := Angle/180*PI;
cn := Cos(Radian);
sn := Sin(Radian);
w1 := Image.Width;
h1 := Image.Height;
w2 := Round(Abs(w1*cn)+Abs(h1*sn));
h2 := Round(Abs(w1*sn)+Abs(h1*cn));
Bitmap := TBitmap.Create;
Bitmap.Width := w2;
Bitmap.Height := h2;
for r2 := 0 to h2-1 do
for c2 := 0 to w2-1 do
begin
x2 := c2 - w2/2;
y2 := r2 - h2/2;
x1 := x2*cn+y2*sn;
y1 :=-x2*sn+y2*cn;
c1 := Round(x1+w1/2);
r1 := Round(y1+h1/2);
if (c1>=0)and(c1<w1)and(r1>=0)and(r1<h1) then
Colour := Image.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
Bitmap.Canvas.Pixels[c2,r2] := Colour;
end;
Image.Picture.Bitmap := Bitmap;
Bitmap.Free;
end;
 
又没传完。只传下半部分。
if (c1>=0)and(c1<w1)and(r1>=0)and(r1<h1) then
Colour := Image.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
Bitmap.Canvas.Pixels[c2,r2] := Colour;
end;
Image.Picture.Bitmap := Bitmap;
Bitmap.Free;
end;

 
Colour := Image.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
Bitmap.Canvas.Pixels[c2,r2] := Colour;
end;
Image.Picture.Bitmap := Bitmap;
Bitmap.Free;
end;
 
if (c1>=0)and(c1<w1)and(r1>=0)and(r1<h1) then
这一句传的时候老出错。不信这个邪。
 
分摊主:帮我整理下。
怎么回事吗?if (c1 >= 0) and (c1 <
w1)and(r1 >= 0) and (r1 < h1) then
老是传断。
 
看能否给过完整的,****!

procedure RotateImage(Image: Timage; Angle: Integer; BColor: TColor);
const
PI=3.1415926;
var
r1, c1: Integer;
r2, c2: Integer;//raw and col control variable
w1, h1: Integer;
w2, h2: Integer;//width and height variable
x1, y1: Double;
x2, y2: Double;//coordinate
cn, sn: Double;
Radian: Double;
Colour: TColor;
Bitmap: TBitmap;
begin
//Calculate radian
Radian := Angle/180*PI;
//Calculate cos(a) and sin(a)
cn := Cos(Radian);
sn := Sin(Radian);
w1 := Image.Width;
h1 := Image.Height;
//Calculate new height and new width
w2 := Round(Abs(w1*cn)+Abs(h1*sn));
h2 := Round(Abs(w1*sn)+Abs(h1*cn));
//Create a new bitmap
Bitmap := TBitmap.Create;
Bitmap.Width := w2;
Bitmap.Height := h2;
for r2 := 0 to h2-1 do
for c2 := 0 to w2-1 do
begin
x2 := c2 - w2/2;
y2 := r2 - h2/2;
x1 := x2*cn+y2*sn;
y1 :=-x2*sn+y2*cn;
c1 := Round(x1+w1/2);//简单取整
r1 := Round(y1+h1/2);//简单取整
if (c1 >= 0) and (c1 < w1) and (r1 >= 0) and (r1 < h1) then
Colour := Image.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
Bitmap.Canvas.Pixels[c2,r2] := Colour;
end;
Image.Picture.Bitmap := Bitmap;
Bitmap.Free;
end;

 
呵呵,可以。
不能用<w, 为什么呢,呵呵:)
 
哦,我明白你的意思了。
吃午饭先,下午帮你再做一个:)
 
卷起千堆雪tyn:我帮你试了好久。
效果还是不行,我旋转一个10m的图像要40多秒。
Photoshop只要5秒。不知你为何要旋转图像?
先贴上刚做完的代码吧,还帮你试试:(
procedure RotateImage(SrcFile, DstFile: String;
Angle: Integer; BColor: TColor; hPb: Integer);
const
PI=3.1415926;
var
r1, c1: Integer;
r2, c2: Integer;//raw and col control variable
w1, h1: Integer;
w2, h2: Integer;//width and height variable
x1, y1: Double;
x2, y2: Double;//coordinate
cn, sn: Double;
Radian: Double;
Colour: TColor;
SrcBitmap: TBitmap;
DstBitmap: TBitmap;
begin
if not FileExists(SrcFile) then Exit;
SrcBitmap := TBitmap.Create;
try SrcBitmap.LoadFromFile(SrcFile);
except SrcBitmap.Free; Exit; end;
//Calculate radian
Radian := Angle/180*PI;
//Calculate cos(a) and sin(a)
cn := Cos(Radian);
sn := Sin(Radian);
w1 := SrcBitmap.Width;
h1 := SrcBitmap.Height;
//Calculate new height and new width
w2 := Round(Abs(w1*cn)+Abs(h1*sn));
h2 := Round(Abs(w1*sn)+Abs(h1*cn));
//Prepare to show progress
SendMessage(hPB,PBM_SETRANGE,0,h2 shl 16);
SendMessage(hPB,PBM_SETPOS,0,0);
//Create a new bitmap
DstBitmap := TBitmap.Create;
DstBitmap.Width := w2;
DstBitmap.Height := h2;
for r2 := 0 to h2-1 do
begin
for c2 := 0 to w2-1 do
begin
x2 := c2 - w2/2;
y2 := r2 - h2/2;
x1 := x2*cn+y2*sn;
y1 :=-x2*sn+y2*cn;
c1 := Round(x1+w1/2);
r1 := Round(y1+h1/2);
if (c1 >= 0) and (c1 < w1) and (r1 >= 0) and ( r1 < h1 ) then
Colour := SrcBitmap.Canvas.Pixels[c1,r1]//插值自己做吧:)
else
Colour := BColor;
DstBitmap.Canvas.Pixels[c2,r2] := Colour;
end;
SendMessage(hPB,PBM_SETPOS,r2+1,0);
end;
DstBitmap.SaveToFile(DstFile);
SrcBitmap.Free;
DstBitmap.Free;
end;
 
reboot:
1)别用pixels,用scanline可以快一些
2)省略x1,x2,y1,y2
3)如果是要重复对多个图像处理,可以先建立一个映射2维数组纪录目标图像点和待处理点
之间的对应关系

 
强烈推荐TFastBmp!
不是控件,是程序单元。
 
对reboot的程序我有个建议,反正不会旋转0。1度,所以你可以建个三角函数表来代替sin、cos
等老牛函数,直接查表快的多,还有可以将所有数据同时扩大10e x被再取整,使其都变为
整数运算,也会快很多。
 
看看这个,可能会有些帮助。是c++的。
http://166.111.136.3/program/programmerhome/Visual%20C++/source%20code/Bitmap/rotate_bitmap.shtml.htm
 
后退
顶部