以鼠标为中心进行缩放,就像使用百度地图时一样。这种方式比一般的以图像中心点为中心进行缩放更加符合人们的思维惯性。
在网上找了没发现现成的,自己研究了半天,绕来绕去,头晕眼花的。后来得到群友的帮助才解决了这个问题。
下面给出由网友霸天虎兄弟提供的方法改写出来的代码:
procedure TForm1.Zoom(I: Single); var NewW, NewH: Integer; NewX, NewY, SX, SY: Integer; A, B: Double; begin FScale := FScale + Round(FScale * I); NewW := Trunc(ImgW * (FScale / 1000)); NewH := Trunc(ImgH * (FScale / 1000)); SX := Image1.Left; SY := Image1.Top; if (NewW < ClientWidth) and (NewH < ClientHeight) then begin // 图像小于窗口时,居中显示 NewX := (ClientWidth - NewW) shr 1; NewY := (ClientHeight - NewH) shr 1; end else begin // 窗口显示不下时 //NewX := SX; //NewY := SY; GetCursorPos(Mouse); Mouse := ScreenToClient(Mouse); //Mouse := Image1.ClientToParent(Mouse); A := (Mouse.X - SX) / Image1.Width; B := (Mouse.Y - SY) / Image1.Height; NewX := SX - Round((NewW - Image1.Width) * A); NewY := SY - Round((NewH - Image1.Height) * B); end; Image1.SetBounds(NewX, NewY, NewW, NewH); end;
从上面的代码中可以看到,首先取得鼠标在图像显示客户区的坐标,然后:
鼠标在缩放前的相对位置 X =(鼠标坐标.X - 图像缩放前坐标.Left) / 图像宽度;
鼠标在缩放前的相对位置 Y =(鼠标坐标.Y - 图像缩放前坐标.Top) / 图像高度;
得到鼠标在缩放前的相对位置后,再用缩放前的坐标 - 乘以缩放后图像大小变化的差值(比如原来大小为A, 新大小为B,差值就是 B - A)。
完整demo下载: http://pan.baidu.com/s/1eQovAsa
http://www.cnblogs.com/yangyxd/articles/3984919.html