0

I was looking at this great example code here on SO Graphics32: Pan with mouse-drag, zoom to mouse cursor with mouse wheel

I am using Delphi Community on win 10 OS. I run the program and the zoom will zoom in, but when I zoom out it goes to the images regular size and doesn't blow up the image .

procedure TForm3.FormCreate(Sender: TObject);
begin
  DoubleBuffered := True;
  Image.Picture.LoadFromFile('C:\PASCHEMATIC.TIFF');
  Image.Stretch := True;
  Image.Height := Round(Image.Width * Image.Picture.Height / 
    Image.Picture.Width);
  FOrgImgBounds := Image.BoundsRect;
end;

procedure TForm3.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
    if FDragging then
    Image.SetBounds(X - FFrom.X, Y - FFrom.Y, Image.Width, Image.Height);
end;

procedure TForm3.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Image.Enabled := True;
  FDragging := False;
end;

procedure TForm3.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;
begin
  MousePos := Image.ScreenToClient(MousePos);
  with Image, MousePos do
  if PtInRect(ClientRect, MousePos) and ((WheelDelta > 0) and
  (Height < Self.ClientHeight) and (Width < Self.ClientWidth)) or
  ((WheelDelta < 0) and (Height > 20) and (Width > 20)) then
  begin
    R := BoundsRect;
    R.Left := Left + X - Round(ZoomFactor[WheelDelta > 0] * X);
    R.Top := Top + Y - Round(ZoomFactor[WheelDelta > 0] * Y);
    R.Right := R.Left + Round(ZoomFactor[WheelDelta > 0] * Width);
    R.Bottom := R.Top + Round(ZoomFactor[WheelDelta > 0] * Height);
    BoundsRect := R;
    Handled := True;
  end;
end;

procedure TForm3.ImageDblClick(Sender: TObject);
begin
  Image.BoundsRect := FOrgImgBounds;
end;

procedure TForm3.ImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if not (ssDouble in Shift) then
  begin
    FDragging := True;
    Image.Enabled := False;
    FFrom := Point(X, Y);
    MouseCapture := True;
  end;
end;

The question is how to get the image to zoom out more to blow up the image?

I have played around with the ZoomFactor values. Seems I have to zoom in before it will zoom out.

Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
grant1842
  • 357
  • 1
  • 7
  • 23

1 Answers1

2

First, a definition: zoom in. So, your question is probably How to zoom in, in order to magnify the image? Or, why doesn't the image zoom in?

The answer is in the FormMouseWheel procedure:

with Image, MousePos do
  if PtInRect(ClientRect, MousePos) and ((WheelDelta > 0) and
  (Height < Self.ClientHeight) and (Width < Self.ClientWidth)) or
  ((WheelDelta < 0) and (Height > 20) and (Width > 20)) then
  begin
    ...

which also reveals the trap of using with ...: it can be hard to see what objects are actually referred to in the code:

(Height < Self.ClientHeight) 
// Height refers to Image.Height, because it is closer in
// scope (because of the with clause,) than e.g. the form,
// which also has an Height property
// Self.ClientHeight refers to Form.ClientHeight because
// Self refers to the object who's method is running

and the same for

(Width < Self.ClientWidth)
// Width refers to Image.Width and Self.ClientWidth refers to Form.ClientWidth

So, the answer to your question is that the image can not become bigger than either extent of the form because of constraints applied in the code.

To remove that constraint, remove

and (Height < Self.ClientHeight) and (Width < Self.ClientWidth)

from the FormMouseWheel() procedure.

Removing those conditions will allow the Image to grow bigger than the form and thereby also the image it contains. At some point, there will be other conditions, like e.g. memory constraints, kicking in.

Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
  • Thanks for your comments . I am still having a little trouble getting it to work. – grant1842 Oct 12 '18 at 23:34
  • Remove the constraint `and (Height < Self.ClientHeight) and (Width < Self.ClientWidth)` from the `FormMouseWheel()` procedure. – Tom Brunberg Oct 13 '18 at 04:46
  • Thanks tom. So (Height < Self.ClientHeight) and (Width < Self.ClientWidth)) was holding the zoom to original size of the image loaded into ther Timage. – grant1842 Oct 13 '18 at 14:25
  • Almost there ;) As I wrote, `Height` refers to `Image.Height` and `Self.ClientHeight` refers to `Form.ClientHeight`. In other words: `(Height < Self.ClientHeight)` restricts the height of the `TImage` to the height of the **form**. Similar for the width: `(Width < Self.ClientWidth)` restricts the width of the `TImage` to the width of the **form**. Removing those conditions will allow the `Image` to grow bigger than the form and thereby also the image it contains. At some point, there will be other conditions, like e.g. memory constraints, kicking in. – Tom Brunberg Oct 14 '18 at 12:23