How to keep relative position of TImage as a Marker on a TImage background image

92 views Asked by At

I am trying to place a number of marker images onto a background image in C++Builder Alexandria 11.3. I can can create them and place them, but cannot keep them in the same position if I resize the image.

Marker positions

EDIT: Removed previouse edit for clarityt...

http://www.mbp.bcbhelper.com

Body diagram with markers added

As mininmal code is needed here to demonstrate a problem I submit this code which is cut down to the max and, in my opinion, requires everything in the example to constitute minimal code, the code contains only the components that would be on you component pallet as they do on mine, please do look at problem and suggest a solution if yo can.

EDIT: Removed code, not relevant to question

@Remy, refer to your last comment this

NewMarkerX = OldMarkerX * (NewImageWidth / OldImageWidth);
NewMarkerY = OldMarkerY * (NewImageHeight / OldImageHeight);

is the same as this, where m[i]->X = is same as NewMarkerX

for(int i = 0; i < m.size(); i++)
    {
    //DrawnMarkerX = (OriginalMarkerX * DrawnImageWidth) / OriginalImageWidth;
    //DrawnMarkerY = (OriginalMarkerY * DrawnImageHeight) / OriginalImageHeight;

    //DrawnMarkerX = (m[i]->X * newImageWidth ) / oldImageWidth;
    //DrawnMarkerY = (m[i]->Y * newImageHeight ) / oldImageHeight;

    m[i]->X = (m[i]->X * newImageWidth ) / oldImageWidth;
    m[i]->Y = (m[i]->Y * newImageHeight ) / oldImageHeight;

    //SetBkMode(Canvas->Handle, TRANSPARENT);
    Canvas->TextOutW(m[i]->image->Left + 10, m[i]->image->Top + 10, IntToStr(m[i]->image->Left) + "," + IntToStr(m[i]->image->Top));
    Canvas->TextOutW(m[i]->image->Left + 10, m[i]->image->Top + 10, IntToStr(m[i]->image->Left) + "," + IntToStr(m[i]->image->Top));

    Canvas->TextOutW(50, 50, IntToStr((int)newImageWidth) + "," + IntToStr((int)newImageHeight));

    }

is this correct, if so it does not work, I have explored other possiblities though but will not go into those as they have been many.

Cheers

1

There are 1 answers

11
Remy Lebeau On

During a resize, you know the old and new sizes of the background image, so its quite easy to calculate new marker positions. Simply take the new image width divided by the old image width, and then multiply the marker's old X position by that value. Repeat for the image height and marker Y position:

NewMarkerX = OldMarkerX * (NewImageWidth / OldImageWidth);
NewMarkerY = OldMarkerY * (NewImageHeight / OldImageHeight);

Or:

NewMarkerX = (OldMarkerX * NewImageWidth) / OldImageWidth;
NewMarkerY = (OldMarkerY * NewImageHeight) / OldImageHeight;

The alternative is to not use manually positioned TImage controls at all. Use TPaintBox instead. In its OnPaint event, you can draw your background image first at the desired size, and then draw each marker at the appropriate position relative to that image size using similar formulas:

DrawnMarkerX = OriginalMarkerX * (DrawnImageWidth / OriginalImageWidth);
DrawnMarkerY = OriginalMarkerY * (DrawnImageHeight / OriginalImageHeight);

Or:

DrawnMarkerX = (OriginalMarkerX * DrawnImageWidth) / OriginalImageWidth;
DrawnMarkerY = (OriginalMarkerY * DrawnImageHeight) / OriginalImageHeight;