📄 unit1.pas
字号:
unit unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtDlgs, Menus, ExtCtrls, ComCtrls, math, ImgList, ToolWin;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N19: TMenuItem;
N20: TMenuItem;
OpenPictureDialog1: TOpenPictureDialog;
SavePictureDialog1: TSavePictureDialog;
StatusBar1: TStatusBar;
PopupMenu1: TPopupMenu;
N90S1: TMenuItem;
N90N1: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
I1: TMenuItem;
O1: TMenuItem;
N10: TMenuItem;
N11: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
N15: TMenuItem;
V1: TMenuItem;
Y1: TMenuItem;
C1: TMenuItem;
N17: TMenuItem;
R1: TMenuItem;
N2: TMenuItem;
Q1: TMenuItem;
Image1: TImage;
procedure N19Click(Sender: TObject);
procedure N20Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure N90S1Click(Sender: TObject);
procedure N90N1Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure I1Click(Sender: TObject);
procedure O1Click(Sender: TObject);
procedure N11Click(Sender: TObject);
procedure N12Click(Sender: TObject);
procedure N15Click(Sender: TObject);
procedure V1Click(Sender: TObject);
procedure Y1Click(Sender: TObject);
procedure C1Click(Sender: TObject);
procedure R1Click(Sender: TObject);
procedure Q1Click(Sender: TObject);
private
//定义开始时间和结束时间变量
BeginTime, EndTime: longint;
//定义用来保存原始图像的位图对象
OldBmp: TBitmap;
//实现远视图效果的函数
procedure bmp_Tilt(const InBmp, OutBmp: TBitmap;
const WidthTop, WidthBottom: integer);
//实现任意角度旋转的功能函数
procedure bmp_eddy(Oribmp, NewBmp: Tbitmap; angle: extended);
//实现扭曲效果的函数
procedure bmp_twist(var Oribmp, NewBmp: TBitmap; Count: integer);
//实现波浪效果的函数
procedure bmp_Wave(XDIV, YDIV, RatioVal: Integer);
//实现缩放的函数
procedure ZoomInOut(bitmap: TBitmap; m, n: extended);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//打开位图文件
procedure TForm1.N19Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
//获取bmp位图文件
image1.Picture.Bitmap.LoadFromFile(OpenPictureDialog1.FileName)
else
exit;
//将选定的bmp文件指定给OldBmp,以实现还原操作
OldBmp.Assign(image1.Picture.Bitmap);
end;
//保存位图文件
procedure TForm1.N20Click(Sender: TObject);
begin
//定义保存图像文件时图像类型为bmp位图文件
SavePictureDialog1.Filter := '*.bmp|*.bmp';
if SavePictureDialog1.Execute then
begin
//保存文件
Image1.Picture.Bitmap.SaveToFile(SavePictureDialog1.FileName + '.bmp');
end;
end;
//窗体创建
procedure TForm1.FormCreate(Sender: TObject);
begin
//设置Image1的属性
Image1.AutoSize := True;
Image1.Stretch := True;
//创建OldBmp位图对象
OldBmp := TBitmap.Create;
//设置打开图像文件时的文件类型
self.OpenPictureDialog1.Filter := '*.bmp|*.bmp';
end;
//顺时针转90度
procedure TForm1.N90S1Click(Sender: TObject);
var
i, J: Integer;
Bmp1, Bmp2: TBitmap;
begin
//创建Tbitmap对象Bmp1和Bmp2
Bmp1 := TBitmap.Create;
Bmp2 := TBitmap.Create;
//将当前图像指定给Bmp1
Bmp1.Assign(Image1.Picture.Graphic);
Bmp2.Height := Image1.Picture.Width;
Bmp2.Width := Image1.Picture.Height;
//设定象素的显示颜色素
Bmp1.PixelFormat := pf24bit;
Bmp2.PixelFormat := pf24bit;
//开始计时
BeginTime := GetTickcount;
for i := 0 to Image1.Height do
begin
for J := 0 to Image1.Width do
begin
//象素点颜色赋值
Bmp2.Canvas.Pixels[(-i + Image1.Height), J] := Bmp1.Canvas.Pixels[J,I];
end;
end;
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' + inttostr(EndTime - BeginTime) + '毫秒';
//显示变化后的图片
Image1.Picture.Bitmap.Assign(Bmp2);
//释放位图对象
Bmp1.Free;
Bmp2.Free;
end;
//逆时针转90度
procedure TForm1.N90N1Click(Sender: TObject);
var
nIdx, nOfs,x, y, i, iMltplier: integer;
iWidth, iHeight, iSize, iLineSize: LongInt;
iBuffer: PChar;
iLine: PByteArray;
begin
//设定象素的显示颜色素
image1.Picture.Bitmap.PixelFormat := pf24bit;
iMltplier := 3;
iWidth := image1.Picture.Bitmap.Height;
iHeight := image1.Picture.Bitmap.Width;
//设定实际需要内存大小
iSize := iWidth * iHeight * iMltplier;
//开始计时
BeginTime := GetTickcount;
//开辟内存
GetMem(iBuffer, iSize);
try
//设定内存块iline的长度
iLineSize := image1.Picture.Bitmap.Width * iMltplier;
//为iLine分配内存
GetMem(iLine, iLineSize);
try
for y := 0 to image1.Picture.Bitmap.Height - 1 do
begin
//进行数据块的移动
Move(image1.Picture.Bitmap.ScanLine[y]^, iLine^, iLineSize);
for x := 0 to image1.Picture.Bitmap.Width - 1 do
begin
nIdx := ((image1.Picture.Bitmap.Width - 1) - x) * iMltplier;
nOfs := (x * iWidth * iMltplier) + (y * iMltplier);
for i := 0 to iMltplier - 1 do
Byte(iBuffer[nOfs + i]) := iLine[nIdx + i];
end;
end;
//宽和高交换开始,逆时针旋转
image1.Picture.Bitmap.Height := iHeight;
image1.Picture.Bitmap.Width := iWidth;
for y := 0 to iHeight - 1 do
begin
//数据移动
nOfs := y * iWidth * iMltplier;
Move((@(iBuffer[nOfs]))^, image1.Picture.Bitmap.ScanLine[y]^, iWidth *
iMltplier);
end;
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
finally
//释放内存iLine
FreeMem(iLine, iLineSize);
end;
finally
//释放内存iBuffer
FreeMem(iBuffer, iSize);
end;
end;
//任意角度旋转
procedure TForm1.N5Click(Sender: TObject);
var
bmp1,bmp2: TBitmap;
angle: integer;
begin
//创建Tbitmap对象bmp1和Bmp2
bmp1 := TBitmap.Create;
bmp2 := TBitmap.Create;
//变换光标形状
screen.Cursor := crhourglass;
//开始计时
BeginTime := GetTickcount;
//将当前图像指定给Bmp1
bmp1.Assign(image1.Picture.Bitmap);
//弹出输入框,让用户输入需要旋转的角度数值
angle := strtoint(inputbox('任意角度旋转位图', '请输入旋转的角度', '90'));
//调用bmp_eddy过程实现旋转操作,旋转后的图像保存在bmp2中
bmp_eddy(bmp1, bmp2, angle);
//显示变化后的图片
image1.picture.Bitmap.Assign(bmp2);
//恢复屏幕光标形状
screen.Cursor := crdefault;
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' + inttostr(EndTime - BeginTime) + '毫秒';
//释放位图对象
bmp1.Free;
bmp2.Free;
end;
//实现任意角度旋转的功能函数
procedure Tform1.bmp_eddy(OriBmp, NewBmp: Tbitmap; angle: extended);
var
c1x, c1y, c2x, c2y: integer;
p1x, p1y, p2x, p2y: integer;
radius, n: integer;
alpha: extended;
c0, c1, c2, c3: tcolor;
begin
//变换位图的格式
if OriBmp.Width > OriBmp.Height then
begin
NewBmp.width := OriBmp.Width;
NewBmp.height := OriBmp.Width;
end
else
NewBmp.Width := OriBmp.Height;
NewBmp.Height := OriBmp.Height;
//将角度转换为PI值
angle := (angle / 180) * pi;
// 计算中心点,可以调整它来获得更好的效果
c1x := OriBmp.width div 2;
c1y := OriBmp.height div 2;
c2x := NewBmp.width div 2;
c2y := NewBmp.height div 2;
// 获得需要的步骤数值,存入n
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 := OriBmp.canvas.pixels[c1x + p1x, c1y + p1y];
c1 := OriBmp.canvas.pixels[c1x - p1x, c1y - p1y];
c2 := OriBmp.canvas.pixels[c1x + p1y, c1y - p1x];
c3 := OriBmp.canvas.pixels[c1x - p1y, c1y + p1x];
NewBmp.Canvas.pixels[c2x + p2x, c2y + p2y] := c0;
NewBmp.canvas.pixels[c2x - p2x, c2y - p2y] := c1;
NewBmp.canvas.pixels[c2x + p2y, c2y - p2x] := c2;
NewBmp.canvas.pixels[c2x - p2y, c2y + p2x] := c3;
end;
//加入处理消息的函数,允许用户在运算期间进行其他操作
application.processmessages;
end;
end;
//缩小
procedure TForm1.I1Click(Sender: TObject);
begin
//开始计时
BeginTime := GetTickcount;
//调用ZoomInOut实现缩小
ZoomInOut(image1.Picture.Bitmap, 0.8, 0.8);
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
end;
//放大
procedure TForm1.O1Click(Sender: TObject);
begin
//开始计时
BeginTime := GetTickcount;
//调用ZoomInOut实现放大
ZoomInOut(image1.Picture.Bitmap, 1.2, 1.2);
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
end;
//实现缩放的函数
procedure TForm1.ZoomInOut(bitmap: TBitmap; m, n: extended);
var
Mybmp: TBitmap;
begin
self.DoubleBuffered := True;
//创建Tbitmap对象mybmp
Mybmp := TBitmap.Create;
//取整数
Mybmp.Width := Trunc(m * Self.Image1.Width);
Mybmp.Height := Trunc(n * self.Image1.Height);
image1.Width := Mybmp.Width;
image1.Height := MyBmp.Height;
//设置指定设备环境中的位图伸展模式
SetStretchBltMode(Mybmp.Canvas.Handle, HalfTone);
//从oldbmp中拷贝图像到mybmp中
Stretchblt(Mybmp.Canvas.Handle, 0, 0, Mybmp.Width,
Mybmp.Height, OldBmp.Canvas.Handle, 0, 0, OldBmp.Width,
OldBmp.Height,SRCCOPY);
//设定象素的显示颜色素
Mybmp.PixelFormat := pf24bit;
//显示变化后的图片
image1.Picture.Bitmap.Assign(MyBmp);
//释放位图对象
MyBmp.Free;
end;
//扭曲效果
procedure TForm1.N11Click(Sender: TObject);
var
bmp1,bmp2: TBitmap;
i: integer;
begin
//若当前无图片,则不做处理
if self.Image1.Picture.Bitmap.Empty then
begin
ShowMessage('请加载图片');
exit;
end
else
//设定象素的显示颜色素
self.Image1.Picture.Bitmap.PixelFormat := pf24bit;
//开始计时
BeginTime := GetTickCount;
//设置状态栏显示内容
statusbar1.simpleText := '';
//创建Tbitmap对象bmp1
bmp1 := TBitmap.Create;
//将当前图像指定给Bmp1
bmp1.Assign(self.Image1.Picture.Bitmap);
//创建Tbitmap对象bmp1
bmp2 := tbitmap.create;
bmp2.width := bmp1.width;
bmp2.height := bmp1.height;
//设定象素的显示颜色素
bmp2.pixelformat := pf24bit;
//设定扭曲程度
i := 100;
//调用bmp_twist实现扭曲
bmp_twist(bmp1, bmp2, i);
//显示变化后的图片
self.Image1.picture.bitmap.assign(bmp2);
//释放位图对象
bmp2.Free;
bmp1.Free;
//获得结束时间
EndTime := GetTickCount;
//显示消耗时间
self.StatusBar1.simpleText :=
' 完成时间: ' + inttostr(EndTime - BeginTime) + '毫秒';
end;
//转换参数值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -