while moving my mouse over a bitmap inside a TImageviewer component in FMX framework, I need to get the position of this pixel inside the original bitmap.
here come my not working code, while zooming and moving to a selected position inside the bitmap, the x/y coordinate change, they should stay independent from the used zoomlevel.
procedure TmainForm.imgviewer_layoutMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var
ImageViewer: TImageViewer;
Image: TBitmap;
ImageX, ImageY: Single;
ScaleX, ScaleY, BitmapScale: Single;
begin
ImageViewer := Sender as TImageViewer;
Image := ImageViewer.Bitmap;
// Ensure we have an image loaded in the ImageViewer
if Assigned(Image) and not Image.IsEmpty then
begin
BitmapScale := Image.BitmapScale;
// Calculate the scale factors of the image within the ImageViewer
ScaleX := ImageViewer.Width / (Image.Width * BitmapScale);
ScaleY := ImageViewer.Height / (Image.Height * BitmapScale);
// Adjust the X, Y to the image coordinates
ImageX := X / ScaleX;
ImageY := Y / ScaleY;
// Ensure coordinates are within the bounds of the image
if (ImageX >= 0) and (ImageX <= Image.Width) and
(ImageY >= 0) and (ImageY <= Image.Height) then
begin
UpdateStatus('INFO LAYOUT DOWN ' + Point2Str(ImageX, ImageY));
end
else
begin
UpdateStatus('INFO LAYOUT DOWN: Outside Image');
end;
end
else
begin
UpdateStatus('INFO LAYOUT DOWN: No Image Loaded');
end;
end;
This should give you what you're after:
procedure TmainForm.imgviewer_layoutMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Single);
var ImageViewer: TImageViewer;
Image: TBitmap;
ImageLeft,
ImageTop: Single;
ImageX,
ImageY: Single;
ScaledImageWidth,
ScaledImageHeight: Single;
Scale: Single;
begin
//Get controls
ImageViewer:=Sender as TImageViewer;
Image:=ImageViewer.Bitmap;
if Assigned(Image) and not Image.IsEmpty then begin
//Get scaled image size
Scale:=Viewer.BitmapScale;
ScaledImageWidth:=Image.Width*Scale;
ScaledImageHeight:=Image.Height*Scale;
//Get bitmap's top and left positions.
ImageLeft:=(ImageViewer.Width-ScaledImageWidth)/2;
if ImageLeft<0 then ImageLeft:=0;
ImageTop:=(ImageViewer.Height-ScaledImageHeight)/2;
if ImageTop<0 then ImageTop:=0;
//Get bitmap's mouse coordinates
ImageX:=(X+ImageViewer.ViewportPosition.X-ImageLeft)/Scale;
ImageY:=(Y+ImageViewer.ViewportPosition.Y-ImageTop)/Scale;
//Report results
if (X>=ImageLeft) and (X<=ImageLeft+ScaledImageWidth)
and (Y>=ImageTop) and (Y<=ImageTop+ScaledImageHeight)
then UpdateStatus('INFO LAYOUT DOWN '+Point2Str(ImageX,ImageY))
else UpdateStatus('INFO LAYOUT DOWN: OutsideImage');
end
else UpdateStatus('INFO LAYOUT DOWN: No Image Loaded');
end;