📄 unit1.pas
字号:
function ArcTan2(xt, yt: Single): Single;
begin
if xt = 0 then
if yt > 0 then
Result := Pi / 2
else
Result := -(Pi / 2)
else
begin
Result := ArcTan(yt / xt);
if xt < 0 then
Result := Pi + ArcTan(yt / xt);
end;
end;
//实现扭曲效果的函数
procedure TForm1.bmp_twist(var Oribmp, Newbmp: TBitmap; Count: integer);
var
fxmid, fymid,txmid, tymid,fx, fy, tx2, ty2, r, theta: Single;
dx, dy,OFFSET,weight,total_red, total_green,total_blue: Single;
weight_x, weight_y: array[0..1] of Single;
ifx, ify,ty, tx,new_red, new_green,new_blue,ix, iy: Integer;
sli, slo: PBytearray;
begin
OFFSET := -(Pi / 2);
dx := Oribmp.Width - 1;
dy := Oribmp.Height - 1;
r := Sqrt(dx * dx + dy * dy);
tx2 := r;
ty2 := r;
//调整参数以移动图像的选择中心
txmid := (Oribmp.Width - 1) / 2;
tymid := (Oribmp.Height - 1) / 2;
fxmid := (Oribmp.Width - 1) / 2;
fymid := (Oribmp.Height - 1) / 2;
if tx2 >= Oribmp.Width then
tx2 := Oribmp.Width - 1;
if ty2 >= Oribmp.Height then
ty2 := Oribmp.Height - 1;
for ty := 0 to Round(ty2) do
begin
for tx := 0 to Round(tx2) do
begin
dx := tx - txmid;
dy := ty - tymid;
r := Sqrt(dx * dx + dy * dy);
if r = 0 then
begin
fx := 0;
fy := 0;
end
else
begin
theta := ArcTan2(dx, dy) - r / Count - OFFSET;
fx := r * Cos(theta);
fy := r * Sin(theta);
end;
fx := fx + fxmid;
fy := fy + fymid;
ify := Trunc(fy);
ifx := Trunc(fx);
//计算weight值
if fy >= 0 then
begin
weight_y[1] := fy - ify;
weight_y[0] := 1 - weight_y[1];
end
else
begin
weight_y[0] := -(fy - ify);
weight_y[1] := 1 - weight_y[0];
end;
if fx >= 0 then
begin
weight_x[1] := fx - ifx;
weight_x[0] := 1 - weight_x[1];
end
else
begin
weight_x[0] := -(fx - ifx);
Weight_x[1] := 1 - weight_x[0];
end;
if ifx < 0 then
ifx := Oribmp.Width - 1 - (-ifx mod Oribmp.Width)
else if ifx > Oribmp.Width - 1 then
ifx := ifx mod Oribmp.Width;
if ify < 0 then
ify := Oribmp.Height - 1 - (-ify mod Oribmp.Height)
else if ify > Oribmp.Height - 1 then
ify := ify mod Oribmp.Height;
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 ify + iy < Oribmp.Height then
sli := Oribmp.scanline[ify + iy]
else
sli := Oribmp.scanline[Oribmp.Height - ify - iy];
if ifx + ix < Oribmp.Width then
begin
new_red := sli[(ifx + ix) * 3];
new_green := sli[(ifx + ix) * 3 + 1];
new_blue := sli[(ifx + ix) * 3 + 2];
end
else
begin
new_red := sli[(Oribmp.Width - ifx - ix)
* 3];
new_green := sli[(Oribmp.Width - ifx -
ix) * 3 +
1];
new_blue := sli[(Oribmp.Width - ifx - ix)
* 3 +
2];
end;
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;
slo := Newbmp.scanline[ty];
slo[tx * 3] := Round(total_red);
slo[tx * 3 + 1] := Round(total_green);
slo[tx * 3 + 2] := Round(total_blue);
end;
end;
end;
//波浪效果
procedure TForm1.N12Click(Sender: TObject);
begin
//若当前无图片,则不做处理
if (image1.Picture.Bitmap = nil) then
showmessage('请加载图片')
else
//调用bmp_Wave实现图片的波浪效果
bmp_Wave(2, 6, 2);
end;
//实现波浪效果的函数
procedure TForm1.bmp_Wave(XDIV, YDIV, RatioVal: Integer);
var
bmp1, bmp2: Tbitmap;
i, j, XSrc, YSrc: Integer;
begin
//如果不需要做波浪效果,则退出
if (XDiv = 0) or (YDiv = 0) then
Exit;
//创建Tbitmap对象bmp1和bmp2
bmp1 := Tbitmap.create;
bmp2 := Tbitmap.Create;
//将当前图像指定给Bmp1和bmp2
bmp2.Assign(self.Image1.Picture.Bitmap);
bmp1.assign(self.Image1.Picture.Bitmap);
//开始计时
BeginTime := gettickcount;
//开始实现波浪效果
for i := 0 to bmp1.Width - 1 do
begin
for j := 0 to bmp1.Height - 1 do
begin
XSrc := Round(i + RatioVal * Sin(j / YDiv));
YSrc := Round(j + RatioVal * sin(i / XDiv));
if XSrc < 0 then
XSrc := Width - 1 - (-XSrc mod Width)
else if XSrc >= Width then
XSrc := XSrc mod Width;
if YSrc < 0 then
YSrc := Height - 1 - (-YSrc mod Height)
else if YSrc >= Height then
YSrc := YSrc mod (Height - 1);
bmp2.Canvas.Pixels[i, j] := bmp1.Canvas.Pixels[XSrc, YSrc];
end;
end;
//显示变化后的图片
self.Image1.Picture.Assign(bmp2);
//获得结束时间
EndTime := gettickcount;
//计算出消耗时间
self.StatusBar1.simpleText := ' 完成时间为:' + IntToStr(EndTime -
BeginTime) + '毫秒';
//释放位图对象
bmp2.Free;
bmp1.Free;
end;
//远视图效果
procedure TForm1.Y1Click(Sender: TObject);
var
inbmp, outbmp: Tbitmap;
begin
//若当前无图片,则不做处理
if Image1.Picture.Bitmap.Empty then
begin
ShowMessage('请加载图片');
exit;
end;
//创建Tbitmap对象inbmp和outbmp
inbmp := TBitmap.Create;
outbmp := TBitmap.Create;
//将当前图像指定给inbmp
inbmp.Assign(image1.Picture.Bitmap);
//开始计时
BeginTime := GetTickcount;
//调用bmp_tilt实现远视图效果
bmp_Tilt(inbmp, outbmp, 200, 400);
//显示变化后的图片
image1.Picture.Bitmap.Assign(outbmp);
image1.Invalidate;
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
//释放位图对象
inbmp.Free;
outbmp.Free;
end;
//实现远视图效果的函数
procedure TForm1.bmp_Tilt(const inbmp, outbmp: TBitmap;
const WidthTop, WidthBottom: integer);
var
y, xWidthDiff, xWidthCurrentLine: Integer;
d: Real;
begin
//设定象素的显示颜色素
outbmp.PixelFormat := inbmp.PixelFormat;
//设置图像参数
if WidthTop > WidthBottom then
outbmp.Width := WidthTop
else
outbmp.Width := WidthBottom;
outbmp.Height := inbmp.Height;
outbmp.Canvas.Brush.Color := clblack;
outbmp.Canvas.FillRect(outbmp.Canvas.ClipRect);
outbmp.Canvas.CopyMode := cmSrcCopy;
//缓慢并高质量地变换图像
SetStretchBltMode(outbmp.Canvas.Handle, HALFTONE);
//设置画刷样式的原点
SetBrushOrgEx(outbmp.Canvas.Handle, 0, 0, nil);
outbmp.Canvas.CopyMode := cmSrcCopy;
d := (WidthBottom - WidthTop) / outbmp.Height;
//开始变换
for y := 0 to outbmp.Height - 1 do
begin
xWidthCurrentLine := Trunc(WidthTop + d * y);
xWidthDiff := (outbmp.Width - xWidthCurrentLine) div 2;
outbmp.Canvas.CopyRect(Rect(xWidthDiff, y, xWidthDiff +
xWidthCurrentLine, y + 1),
inbmp.Canvas, Rect(0, y, inbmp.Width, y + 1));
end;
end;
//水平镜像
procedure TForm1.N15Click(Sender: TObject);
var
bmp1, bmp2, bmp3: TBitmap;
T, P: pByteArray;
X, Y: integer;
begin
//创建Tbitmap对象bmp1、bmp2和bmp3
bmp1 := TBitmap.Create;
bmp2 := TBitmap.Create;
bmp3 := TBitmap.Create;
//将当前图像指定给bmp1和bmp2
bmp1.Assign(Image1.Picture.Bitmap);
bmp2.Assign(Image1.Picture.Bitmap);
//设置bmp3的样式
bmp3.Width := 2 * bmp1.Width;
bmp3.Height := Image1.Picture.Bitmap.Height;
//开始计时
BeginTime := GetTickcount;
//开始变换
for Y := 0 to bmp2.Height - 1 do
begin
T := bmp2.ScanLine[Y];
P := bmp1.ScanLine[Y];
for X := 0 to bmp2.Width - 1 do
begin
P[3 * X + 2] := T[3 * (bmp2.Width - 1 - X) + 2];
P[3 * X + 1] := T[3 * (bmp2.Width - 1 - X) + 1];
P[3 * X] := T[3 * (bmp2.Width - 1 - X)];
end;
end;
bmp3.Canvas.Draw(0, 0, bmp2);
bmp3.Canvas.Draw(bmp2.Width, 0, bmp1);
//显示变化后的图片
Image1.Picture.Bitmap.Assign(bmp3);
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
//释放位图对象
bmp1.Free;
bmp2.Free;
bmp3.Free;
end;
//垂直镜像
procedure TForm1.V1Click(Sender: TObject);
var
bmp1, bmp2, bmp3: Tbitmap;
i, j: integer;
p, p1: pbyteArray;
begin
//创建Tbitmap对象bmp1、bmp2和bmp3
bmp1 := Tbitmap.Create;
bmp2 := Tbitmap.Create;
bmp3 := Tbitmap.Create;
//将当前图像指定给bmp1和bmp2
bmp1.Assign(Self.Image1.Picture.Bitmap);
bmp2.Assign(Self.image1.Picture.Bitmap);
//设置bmp3的样式
bmp3.Width := bmp1.Width;
bmp3.Height := 2 * bmp1.Height;
//设定象素的显示颜色素
bmp1.PixelFormat := pf24bit;
bmp2.PixelFormat := pf24bit;
//开始计时
BeginTime := GetTickcount;
//开始变换
for j := 0 to Self.image1.Picture.Graphic.Height - 1 do
begin
p := bmp1.ScanLine[j];
p1 := bmp2.ScanLine[Self.IMAGE1.Picture.Graphic.Height - 1 - j];
for i := 0 to Self.image1.Picture.Graphic.Width - 1 do
begin
p[3 * i] := p1[3 * i];
p[3 * i + 1] := p1[3 * i + 1];
p[3 * i + 2] := p1[2 + 3 * i];
end;
end;
bmp3.Canvas.Draw(0, 0, bmp2);
bmp3.Canvas.Draw(0, bmp1.Height, bmp1);
bmp3.PixelFormat := pf24bit;
//显示变化后的图片
Self.Image1.Picture.Bitmap.Assign(bmp3);
Self.image1.picture.Bitmap.PixelFormat := pf24bit;
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
//释放位图对象
bmp1.Free;
bmp2.Free;
bmp3.Free;
end;
//裁剪图像
procedure TForm1.C1Click(Sender: TObject);
var
rgn1: Hrgn;
Bmp1: TBitmap;
begin
//创建Tbitmap对象bmp1
Bmp1 := TBitmap.Create;
//将当前图像指定给bmp1
Bmp1.Assign(Image1.Picture.Bitmap);
//开始计时
BeginTime := GetTickcount;
//创建剪切区域
rgn1 := CreateRectRgn(40, 40, 500, 300);
//选中剪裁区域
SelectclipRgn(Image1.Canvas.Handle, rgn1);
//清空图像
Image1.Picture := nil;
//通过拷贝将图像显示在界面上
BitBlt(Image1.Canvas.Handle, 40, 40, 500, 300, Bmp1.Canvas.Handle, 0, 0,
SRCCOPY);
//获得结束时间
EndTime := GetTickcount;
//计算出消耗时间
self.StatusBar1.simpleText:= '执行时间为:' +
inttostr(EndTime - BeginTime) + '毫秒';
//释放位图对象
Bmp1.Free;
end;
//还原图像
procedure TForm1.R1Click(Sender: TObject);
begin
//还原图像
image1.Picture.Bitmap.Assign(OldBmp);
end;
procedure TForm1.Q1Click(Sender: TObject);
begin
//释放位图对象
OldBmp.Free;
Close;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -