给个能旋转image中图像90度和180度的代码(100分)

  • 主题发起人 主题发起人 ruelm
  • 开始时间 开始时间
R

ruelm

Unregistered / Unconfirmed
GUEST, unregistred user!
我找到了这段
var
i,j:Integer;
rowIn,rowOut:pRGBTriple;
Bmp:TBitmap;
Width,Height:Integer;
begin
Bmp:=TBitmap.Create;
Bmp.Width := img1.Height;
Bmp.Height := img1.Width;
Bmp.PixelFormat := pfDevice;
Width:=img1.Width-1;
Height:=img1.Height-1;
for j := 0 to Height do
begin
rowIn := img1.Picture.Bitmap.ScanLine[j];
for i := 0 to Width do
begin
rowOut := Bmp.ScanLine;
Inc(rowOut,Height-j);
rowOut^ := rowIn^;
Inc(rowIn);
end;
end;
img1.Picture.Assign(Bmp);
end;
怎么老是 scan line index out of range ,
应该怎么写
相关资料
scan lin 的资料 http://bluemoon.diy.myrice.com/efg/scanline.htm
图像旋转笔记 http://www.delphibbs.com/keylife/iblog_show.asp?xid=4499
还望大侠宽恕我的愚笨,指教一二,
 
procedure RotateBmp(bmp: TBitmap; Center: TPoint; angle: Integer);
var
tmpbmp: TBitmap;
i, j, x, y, px, py: Integer;
cAngle, sAngle: extended;
p1, p2: Pchar;
begin
while angle < 0 do
angle := angle + 360;
angle := angle mod 360;
sAngle := sin(- angle * pi / 180);
cAngle := cos(- angle * pi / 180);
tmpbmp := tbitmap.create;
tmpbmp.assign(bmp);
for i := 0 to tmpbmp.height - 1 do
begin
p1 := pchar(tmpbmp.scanline);
py := 2 * (i - center.y) - 1;
for j := 0 to tmpbmp.width - 1 do
begin
px := 2 * (j - center.x) - 1;
x := (round(px * cAngle - py * sAngle) - 1) div 2 + center.x;
y := (round(px * sAngle + py * cAngle) - 1) div 2 + center.y;
if (x>=0) and (x<tmpbmp.width) and (y>=0) and (y<=tmpbmp.height) then
begin
p2 := pchar(bmp.scanline[y]) + x * 3;
move(p1^, p2^, 3);
end;
inc(p1, 3);
end;
end;
end;
 
怎么使用,center取什么值?
 
抄来的.....
{ 旋转图像特效
输入参数:
Image 要进行旋转特效的TImage
Angle 旋转的角度(以度为单位,例如90表示旋转90度)
SleepTime 特效的快慢控制
}
procedure Img_Rotate(Image:TImage;Angle:Extended;SleepTime:Word);
var
c1x,c1y,c2x,c2y:Integer;
p1x,p1y,p2x,p2y:Integer;
radius,n:Integer;
alpha:Extended;
c0,c1,c2,c3:TColor;
OldBmp:TBitmap;
begin
OldBmp:=TBitmap.Create;
try
OldBmp.Assign(Image.Picture.Graphic);
Image.Picture:=nil;
angle:=(Angle/180)*PI; //将角度转换为PI值
// 计算中心点
c1x:=OldBmp.Width div 2;
c1y:=OldBmp.Height div 2;
c2x:=c1x;
c2y:=c1y;
// 步骤数值number
if c2x < c2y then n:=c2y
else n:=c2x;
Dec(n,1);
// 开始旋转
for p2x:=0 to n do
begin
for p2y:=0 to n do
begin
if p2x=0 then alpha:=PI/2
else alpha:=ArcTan2(p2y,p2x);
radius:=Round(Sqrt((p2x*p2x)+(p2y*p2y)));
p1x:=Round(radius*Cos(angle+alpha));
p1y:=Round(radius*Sin(angle+alpha));

c0:=OldBmp.Canvas.Pixels[c1x+p1x,c1y+p1y];
c1:=OldBmp.Canvas.Pixels[c1x-p1x,c1y-p1y];
c2:=OldBmp.Canvas.Pixels[c1x+p1y,c1y-p1x];
c3:=OldBmp.Canvas.Pixels[c1x-p1y,c1y+p1x];

Image.Canvas.Pixels[c2x+p2x,c2y+p2y]:=c0;
Image.Canvas.Pixels[c2x-p2x,c2y-p2y]:=c1;
Image.Canvas.Pixels[c2x+p2y,c2y-p2x]:=c2;
Image.Canvas.Pixels[c2x-p2y,c2y+p2x]:=c3;
Image.Refresh;
Sleep(SleepTime);
end;
end;
finally
OldBmp.Free;
end;
end;
 
楼上的代码中sleeptime,怎么用设为什么,怎么cpu占有率很高,
是不是用了计算函数的缘故,
我想还是scanline 比较好,
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=662702
也说了 scan line 的边界错误,ScanLine的Index取范围:0 to Bitmap.Height - 1
而每行的范围与PixelFormat有关.
http://bluemoon.diy.myrice.com/efg/scanline.htm
里面提到
pf24bit的位图

关于pf24bit位图,我定义了(我希望Borland也会这么做)下面的表7,其中的内容和TByteArray类型差不多
表7 TRGBTripleArray 的定义
CONST
PixelCountMax = 32768;
TYPE
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = ARRAY[0..PixelCountMax-1] OF TRGBTriple;

用这么大的PixelCountMax有这么两个目的,一个是限制位图大小,一个是关闭对Scanline变量范围的检查。

当表7对像素范围索引值做了一些限制时(你可能会用到更小一些的PixelCounetMax),你可以用下面的定义,它更加简单一些:

TYPE TRGBTripleArray = Array [WORD] OF TRGBTriple;
Borland在Graphics.PAS中定义了TRGBTripleArray,但是这是一个字节的类型。

Danny Thorpe(Borland R & D)的评语:

这是因为这个数组是用来处理调色板的。它并非用来访问像素。你会注意到它在D1~D4中的改进,我已经在位图常规中去掉了许多临时内存的分配。在许多节约时间的方案中,有一种就是不分配大堆的临时内存给调色板。就这一点而言,我只是用了一个局部变量:256 RGBTriples,这个变量的大小由我的需要来决定。这样的方式会用掉700~1K的堆栈空间,但是堆栈在win32中是很廉价的,它会在几个时间片的时间里回收利用。 如果你用WORD来定义RGBTriples,那么上面说的效用就没有了,它不会堆栈,显然也比较昂贵。
因为字节能表示的范围是0~255,所以Borland公司定义的TRGBTripleArray甚至在一般的位图操作上都会出错。我定义的TRGBTripleArray就不会了。

我应该在程序中哪儿修改啊
 
想把视频中的每一帧保存成一个图片,如果保存在硬盘中太慢,现在想保存为jpg流,
stream:=TMemoryStream.Create;
ImageEnViewview.IO.SaveToStreamJpeg(stream);
stream.Position:=0;
fjpg:=TJPEGImage.Create();
fjpg.LoadFromStream(stream);
jpegarray:=fjpg;
i:=i+1;

但在读取的时候出现错误。。。。帮助看一下。。
 
楼上还有7百多分啊^_^
 
一个能够旋转显示其内的图像的Image控件RotImage,从网上下载,可以去试试,方便。
 
^_^ 找到了控件RotImage的源码 学习了,改造为我所用,
很感谢officegod ,当然还有bjaman cqwty ,

http://www.delphiarea.com/products/
 
后退
顶部