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

本文介绍了一种视频播放窗口的缩放算法,通过计算可视区域来实现以鼠标为中心的缩放效果。该算法考虑了边界条件,并允许放大后的图像进行拖动漫游。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

应用场景:视频播放窗口缩放,最小保持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);

Demo下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值