You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Delphi Firemonkey中TImage组件内显示图像的宽高?

Firemonkey中获取TImage显示图像的实际尺寸及坐标映射方法

在Firemonkey的TImage组件中,当图片按适配模式(默认WrapMode=Fit)自动缩放显示时,要获取当前显示图像的实际宽高,并将鼠标坐标映射到原始位图,可通过以下方法实现:

一、计算显示图像的实际尺寸

通过对比原始位图和TImage组件的宽高比例,计算出适配后的显示尺寸:

function GetDisplayedImageSize(AImage: TImage): TSizeF;
var
  ImageRatio, ControlRatio: Single;
begin
  Result := TSizeF.Create(0, 0);
  if (AImage.Bitmap = nil) or (AImage.Bitmap.Width = 0) or (AImage.Bitmap.Height = 0) then
    Exit;

  ImageRatio := AImage.Bitmap.Width / AImage.Bitmap.Height;
  ControlRatio := AImage.Width / AImage.Height;

  // 适配模式(Fit)下的尺寸计算
  if ImageRatio > ControlRatio then
  begin
    // 图像宽高比大于控件,以控件宽度为基准缩放
    Result.Width := AImage.Width;
    Result.Height := AImage.Width / ImageRatio;
  end
  else
  begin
    // 图像宽高比小于控件,以控件高度为基准缩放
    Result.Height := AImage.Height;
    Result.Width := AImage.Height * ImageRatio;
  end;
end;

如果使用其他WrapMode(如Stretch拉伸填充、Center居中显示),可在函数中补充判断:

case AImage.WrapMode of
  TImageWrapMode.Stretch:
    Result := TSizeF.Create(AImage.Width, AImage.Height);
  TImageWrapMode.Center:
    Result := TSizeF.Create(AImage.Bitmap.Width, AImage.Bitmap.Height);
end;

二、将鼠标坐标映射到原始位图

先计算显示图像在TImage内的偏移量(适配模式下会居中),再通过缩放比例转换鼠标坐标:

function MapMousePosToBitmap(AImage: TImage; AMousePos: TPointF): TPointF;
var
  DisplayedSize: TSizeF;
  ScaleX, ScaleY: Single;
  OffsetX, OffsetY: Single;
begin
  Result := TPointF.Create(-1, -1);
  if (AImage.Bitmap = nil) or (AImage.Bitmap.Width = 0) or (AImage.Bitmap.Height = 0) then
    Exit;

  DisplayedSize := GetDisplayedImageSize(AImage);
  // 计算原始位图与显示图像的缩放比例
  ScaleX := AImage.Bitmap.Width / DisplayedSize.Width;
  ScaleY := AImage.Bitmap.Height / DisplayedSize.Height;

  // 计算显示图像在控件内的居中偏移
  OffsetX := (AImage.Width - DisplayedSize.Width) / 2;
  OffsetY := (AImage.Height - DisplayedSize.Height) / 2;

  // 转换坐标:鼠标位置减去偏移后,乘以缩放比例
  Result.X := (AMousePos.X - OffsetX) * ScaleX;
  Result.Y := (AMousePos.Y - OffsetY) * ScaleY;

  // 确保坐标在原始位图的有效范围内
  Result.X := Max(0, Min(Result.X, AImage.Bitmap.Width - 1));
  Result.Y := Max(0, Min(Result.Y, AImage.Bitmap.Height - 1));
end;

三、使用示例

在TImage的OnMouseMove事件中调用上述函数,即可实时获取显示尺寸和对应位图坐标:

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
var
  DisplayedSize: TSizeF;
  BitmapPos: TPointF;
begin
  DisplayedSize := GetDisplayedImageSize(Image1);
  // 显示当前图像的实际显示尺寸
  Caption := Format('显示尺寸: %d x %d', [Round(DisplayedSize.Width), Round(DisplayedSize.Height)]);

  BitmapPos := MapMousePosToBitmap(Image1, TPointF.Create(X, Y));
  // 显示鼠标对应的原始位图坐标
  lblBitmapPos.Text := Format('位图坐标: %d, %d', [Round(BitmapPos.X), Round(BitmapPos.Y)]);
end;

内容的提问来源于stack exchange,提问作者fisi-pjm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:42:39