delphi以鼠标为中心缩放图片以及拖动(采用区域抠图拉伸的方式)


本文整理自网络,侵删。

 
应用场景:视频播放窗口缩放,最小保持100%

帧图像:视频中的一帧图像

视口:用于显示视频的区域

可视区域:帧图像中某一块区域,拉伸后贴图到视口

说明:当鼠标在视口中任意位置滚动滚轮,向上放大时可视区域变小,向下缩小时可视区域变大,将可视区域内的图像拉伸贴图到视口,即实现缩放效果。


要达到以鼠标为中心缩放的目的,必须对可视区域进行相应计算,以下是伪代码说明:
Bmp := TBitmap.Create;//帧图像初始化
Bmp.LoadFormFile('1.bmp');
ViewRect := Rect(0, 0, Bmp.Width, Bmp.Height);//可视区域初始化

//在鼠标滚轮事件中实现以下代码
if WheelDelta > 0 then
begin
  //比例因子以100%递增
  if Scale > 32 then exit;
  Inc(Scale);
end
else
begin
  //缩小时以100%递减
  if Scale <= 1 then exit
  Dec(Scale);
end;

//1.计算出放大N倍时可视区域的宽和高
W := Bmp.Width div Scale;
H := Bmp.Height div Scale;
if Scale = 1 then//不允许缩小
begin
  L := 0;
  T := 0;
end
else
begin
//2.计算出可视区域
  pt := ScreenToClient(MousePos);
  sx := pt.x / Bmp.Width;//鼠标位置在视口位置的百分比
  sy := pt.y / Bmp.Height;
  SW := ViewRect.Right - ViewRect.Left;
  SH := ViewRect.Bottom - ViewRect.Top;
  L := ViewRect.Left + Round((SW - W) * sx);//缩放前后区域宽和高乘以鼠标位置占比,得出可视区域坐标移动范围
  T := ViewRect.Top + Round((SH - H) * sy);
  if L < 0 then L := 0;//防止左边越界
  if L + W > Bmp.Width then L := Bmp.Width - W;//防止右边越界
  if T < 0 then T := 0;//防止上边越界
  if T + H > Bmp.Height then T := Bmp.Height - H;//防止下边越界
end;
ViewRect := Rect(L, T, L + W, T + H);//计算出可视区域
DestImage.Canvas.CopyRect(DestImage.BoundsRect, Bmp.Canvas, ViewRect);//将可视区域中的图块拉伸并贴图到视口

//放大后的图像拖动漫游,
//在OnMouseDown事件中记录鼠标按下状态和鼠标位置,在OnMouseUp中释放鼠标按下状态
//在MouseMove事件中处理
if IsMouseDown or (Scale < 2) then exit;
sx := Round((X - ImageDownX) / Scale);//拖动距离按比例缩放,比如在4倍放大时拖动4个像素,可视区域实际只移动一个像素
sy := Round((Y - ImageDownY) / Scale);
if sx > 0 then//向右拖
begin
  if sx > ViewRect.Left then//防止越界
    sx := ViewRect.Left;
end
else if sx < 0 then//向左拖
begin
  if Abs(sx) > Bmp.Width - ViewRect.Right then//防止越界
    sx := Bmp.Width - ViewRect.Right;
end;
if sy > 0 then//向下拖
begin
  if sy > ViewRect.Top then//防止越界
    sy := ViewRect.Top;
end
else if sy < 0 then//向上拖
begin
  if Abs(sy) > Bmp.Height - ViewRect.Bottom then//防止越界
    sy := Bmp.Height - ViewRect.Bottom;
end;

ImageDownX := X;
ImageDownY := Y;
if (sx = 0) and (sy = 0) then Exit;
OffsetRect(ViewRect, -sx, -sy);
DestImage.Canvas.CopyRect(DestImage.BoundsRect, Bmp.Canvas, ViewRect);

来源:https://blog.csdn.net/cmd9x/article/details/79897086

相关阅读 >>

Delphi 泛型数组 strsplit 字符串分割

Delphi 官方stylebook大全使用

Delphi如何开发游戏外挂

Delphi编辑环境

Delphi实现百度地图经纬度与地址互转

Delphi xe10 获取屏幕截图

Delphi tbytedynarray转化为string

Delphi Delphi中点击dbgrid某一行获得其详细数据方法

Delphi检查是否在64位windows环境中运行?

Delphi控制面板应用大全

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...