如何获取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
相关产品推荐
相关产品推荐

