FireMonkey TImageViewer缩放时如何计算源图像可见区域坐标?
TImageViewer点击时计算源图像坐标(支持缩放与滚动)
在使用TImageViewer实现带缩放、滚动的图像查看功能时,需要将鼠标点击的视口坐标转换为源图像的原始坐标。原代码仅在未缩放场景下有效,核心问题是未正确结合缩放比例与视口偏移量进行计算,以下是修正后的实现方案:
procedure TfmxFirebaseDemo.imvAnotateFileMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); var ContentPos: TPointF; SourcePos: TPoint; Relative: TPointF; Scale: Single; begin // 获取当前图像的缩放比例 Scale := imvAnotateFile.BitmapScale; // 计算鼠标点击位置在缩放后完整图像上的坐标 // ViewportPosition是视口左上角相对于缩放后图像的偏移量,叠加鼠标视口坐标得到内容坐标 ContentPos.X := X + imvAnotateFile.ViewportPosition.X; ContentPos.Y := Y + imvAnotateFile.ViewportPosition.Y; // 将缩放后的内容坐标转换为源图像的原始像素坐标 SourcePos.X := Round(ContentPos.X / Scale); SourcePos.Y := Round(ContentPos.Y / Scale); // 计算相对坐标(范围0-1,对应源图像的百分比位置) Relative.X := ContentPos.X / (imvAnotateFile.Bitmap.Width * Scale); Relative.Y := ContentPos.Y / (imvAnotateFile.Bitmap.Height * Scale); FMX.Types.Log.d('源图像坐标 %d, %d 相对坐标 %f, %f 缩放比例 %f', [SourcePos.X, SourcePos.Y, Relative.X, Relative.Y, Scale]); end;
关键说明:
- BitmapScale:直接获取TImageViewer当前的图像缩放比例,无需自行推导,该属性准确反映了图像的缩放倍数。
- ViewportPosition:表示视口左上角相对于缩放后完整图像的偏移量(即滚动条滚动的距离),将鼠标在视口内的坐标与该偏移量相加,就能得到点击位置在缩放后图像上的绝对坐标。
- 坐标转换逻辑:缩放后的图像坐标除以缩放比例,即可还原为源图像的原始像素坐标,该逻辑在图像缩放、滚动时均适用。
- 关于视口尺寸:TImageViewer的视口实际可见大小等价于组件的
ClientWidth和ClientHeight(滚动条显示时,该值会自动扣除滚动条占用的空间),本场景无需直接使用视口尺寸即可完成坐标转换。
内容的提问来源于stack exchange,提问作者Schneider Infosystems Ltd
相关产品推荐
相关产品推荐

