本文整理自网络,侵删。
应用场景:视频播放窗口缩放,最小保持100%
帧图像:视频中的一帧图像
视口:用于显示视频的区域
可视区域:帧图像中某一块区域,拉伸后贴图到视口
说明:当鼠标在视口中任意位置滚动滚轮,向上放大时可视区域变小,向下缩小时可视区域变大,将可视区域内的图像拉伸贴图到视口,即实现缩放效果。
要达到以鼠标为中心缩放的目的,必须对可视区域进行相应计算,以下是伪代码说明:Bmp := TBitmap.Create;//帧图像初始化Bmp.LoadFormFile('1.bmp');ViewRect := Rect(0, 0, Bmp.Width, Bmp.Height);//可视区域初始化
//在鼠标滚轮事件中实现以下代码if WheelDelta > 0 thenbegin //比例因子以100%递增 if Scale > 32 then exit; Inc(Scale);endelsebegin //缩小时以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;endelsebegin//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;endelse 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;endelse 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 Delphi中点击dbgrid某一行获得其详细数据方法
更多相关阅读请进入《Delphi》频道 >>