FMX TImageViewer获取原始位图鼠标像素坐标问题(含错误代码)
解决FMX TImageViewer中获取鼠标下原始位图像素坐标的问题
你的代码无法正确获取原始像素坐标,核心问题是忽略了TImageViewer的滚动偏移,且错误地自行计算缩放比例。以下是修正后的实现:
修正后的代码
procedure TmainForm.imgviewer_layoutMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); var ImageViewer: TImageViewer; Image: TBitmap; LocalPos, ImagePos: TPointF; BitmapScale: Single; begin ImageViewer := Sender as TImageViewer; Image := ImageViewer.Bitmap; if Assigned(Image) and not Image.IsEmpty then begin // 计算鼠标相对于图像显示区域的坐标(减去滚动偏移) LocalPos.X := X - ImageViewer.ViewPortPosition.X; LocalPos.Y := Y - ImageViewer.ViewPortPosition.Y; BitmapScale := Image.BitmapScale; // 转换为原始位图的像素坐标:结合组件缩放比例与高DPI适配因子 ImagePos.X := LocalPos.X / (ImageViewer.Scale.X * BitmapScale); ImagePos.Y := LocalPos.Y / (ImageViewer.Scale.Y * BitmapScale); // 校验坐标是否在原始位图范围内 if (ImagePos.X >= 0) and (ImagePos.X <= Image.Width) and (ImagePos.Y >= 0) and (ImagePos.Y <= Image.Height) then begin // 如需整数像素坐标,可使用Round或Trunc处理 UpdateStatus(Format('INFO LAYOUT DOWN 原始像素坐标: (%.0f, %.0f)', [ImagePos.X, ImagePos.Y])); end else begin UpdateStatus('INFO LAYOUT DOWN: 不在图像范围内'); end; end else begin UpdateStatus('INFO LAYOUT DOWN: 未加载图像'); end; end;
关键修正点
- 滚动偏移处理:使用
ViewPortPosition获取图像的滚动偏移量,鼠标坐标需先减去该值,才能得到相对于图像显示区域的位置。 - 正确的缩放比例:直接使用TImageViewer内置的
Scale属性,而非自行计算容器与图像的宽高比,该属性准确反映了当前图像的缩放状态。 - 高DPI适配:结合位图的
BitmapScale因子,确保在高分辨率屏幕下坐标转换的准确性。
内容的提问来源于stack exchange,提问作者Franz
相关产品推荐
相关产品推荐

