delphi - Zoom at mouse cursor using TImage - Stack Overflow

I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Rece

I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Recently I was asked to implement a zooming functionality in that form. It's not a mandatory requirement, but I was trying with a zoom triggered by the mouse wheel, and centered at the mouse cursor.

I got the code suggested here

procedure TfrmVisualizaImagem.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
  ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
  R: TRect;
  Postion: TPoint;
begin
  Position := ImgRecibo.ScreenToClient(MousePos);
  if PtInRect(imgRecibo.ClientRect, Position) and ((WheelDelta > 0) or
      ((WheelDelta < 0) and (imgRecibo.Height > 20) and (imgRecibo.Width > 20))) then
    begin
    R := imgRecibo.BoundsRect;
    R.Left := imgRecibo.Left + Position.X - Round(ZoomFactor[WheelDelta > 0] * Position.X);
    R.Top := imgRecibo.Top + Position.Y - Round(ZoomFactor[WheelDelta > 0] * Position.Y);
    R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Width);
    R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Height);
    imgRecibo.BoundsRect := R;
    Handled := True;
    end;
end;

At first glance it works fine, but after zooming in a few times the image begin to slide to the right and up. I put a memo in the form to visualize what was happening inside the Mouse wheel event and I realized that, even with the mouse steady at the same point, after a few zooming in, the MousePos began to change.

MousePos: 851,439 Position: 215,175 Rect: -22,-18,690,989 Imagem: 712,1007

MousePos: 851,439 Position: 237,193 Rect: -46,-37,737,1071 Imagem: 783,1108

MousePos: 851,439 Position: 261,212 Rect: -72,-58,789,1161 Imagem: 861,1219

MousePos: 851,439 Position: 287,233 Rect: -101,-81,846,1260 Imagem: 947,1341

MousePos: 851,439 Position: 316,256 Rect: -133,-107,909,1368 Imagem: 1042,1475

MousePos: 984,546 Position: 481,389 Rect: -181,-146,965,1477 Imagem: 1146,1623*

So, anyone knows why this is happening and how to fix it?

I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Recently I was asked to implement a zooming functionality in that form. It's not a mandatory requirement, but I was trying with a zoom triggered by the mouse wheel, and centered at the mouse cursor.

I got the code suggested here

procedure TfrmVisualizaImagem.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
const
  ZoomFactor: array[Boolean] of Single = (0.9, 1.1);
var
  R: TRect;
  Postion: TPoint;
begin
  Position := ImgRecibo.ScreenToClient(MousePos);
  if PtInRect(imgRecibo.ClientRect, Position) and ((WheelDelta > 0) or
      ((WheelDelta < 0) and (imgRecibo.Height > 20) and (imgRecibo.Width > 20))) then
    begin
    R := imgRecibo.BoundsRect;
    R.Left := imgRecibo.Left + Position.X - Round(ZoomFactor[WheelDelta > 0] * Position.X);
    R.Top := imgRecibo.Top + Position.Y - Round(ZoomFactor[WheelDelta > 0] * Position.Y);
    R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Width);
    R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * imgRecibo.Height);
    imgRecibo.BoundsRect := R;
    Handled := True;
    end;
end;

At first glance it works fine, but after zooming in a few times the image begin to slide to the right and up. I put a memo in the form to visualize what was happening inside the Mouse wheel event and I realized that, even with the mouse steady at the same point, after a few zooming in, the MousePos began to change.

MousePos: 851,439 Position: 215,175 Rect: -22,-18,690,989 Imagem: 712,1007

MousePos: 851,439 Position: 237,193 Rect: -46,-37,737,1071 Imagem: 783,1108

MousePos: 851,439 Position: 261,212 Rect: -72,-58,789,1161 Imagem: 861,1219

MousePos: 851,439 Position: 287,233 Rect: -101,-81,846,1260 Imagem: 947,1341

MousePos: 851,439 Position: 316,256 Rect: -133,-107,909,1368 Imagem: 1042,1475

MousePos: 984,546 Position: 481,389 Rect: -181,-146,965,1477 Imagem: 1146,1623*

So, anyone knows why this is happening and how to fix it?

Share Improve this question edited Feb 4 at 19:05 Luis Enrique asked Feb 3 at 2:25 Luis EnriqueLuis Enrique 111 silver badge2 bronze badges 3
  • Your MousePos variable does not represent the position of the mouse on the screen, but the position in the ImgRecibo control. And you move that control with setting its BoundRect. Please show us your code that writes the output. – NGLN Commented Feb 4 at 14:56
  • Why it should be the position in the ImgRecibo if the event I'm working is the FormMouseWheel? so, is an event of the form. I think Maybe the code is a little confusing cause is changing the MousePos parameter. When I got that output, I use another variable called Position. I will edit the code above to show that – Luis Enrique Commented Feb 4 at 19:02
  • I hope it becomes clearer now. When I say MousePos I'm talking about the parameter received on the event. – Luis Enrique Commented Feb 4 at 19:08
Add a comment  | 

2 Answers 2

Reset to default 2

When you calculate some positions with rounding a lot of times, small errors are accumulated, so you can see shifting and sometimes diistortions.

You have to exclude recalculating based on current position.

Instead calculate shift and scale factors and apply it on initial coordinates

This is happening because you have Proportional property set to true.

What Proportional property does is it shrinks the image in order to fit the control while maintaining the aspect ration. But if the size of TImage is larger than the dimensions of the picture the picture never gets stretched in order to fit the TImage control.

And since picture position within TImage control is always aligned to top left corner and you are changing the position of your TImage control it seems as the image starts moving in left and up direction.


How to solve this? Instead of setting Proportional property to True set the Stretch property to True.

However you will need to make sure that you adjust the Width and Height of your TImage in order to maintain aspect ratio of the loaded picture. After that your code will work just nicely.

How do you do this? Check the FormCreate event method in the linked SO answer you got your code from.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745251772a4618720.html

相关推荐

  • delphi - Zoom at mouse cursor using TImage - Stack Overflow

    I have a VCL MDI Application in Delphi 10.4, and I have an image browser in it using a modal form. Rece

    5小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信