Не вдаваясь в подробности, я предполагаю, что вы действительно страдаете от ошибок округления ...
- Когда вы масштабируете (вверху, слева) координату обратно к оригиналу, вам нужно округлитьвниз (к верхнему левому углу).
- Когда вы масштабируете (нижнюю, правую) координату обратно к оригиналу, вам нужно округлить вверх (к нижнему правому углу)
Возьмите простой примерсетки 12x12 в качестве оригинала и сетки 4x4 в качестве масштабированной версии.
- (1,1) :( 2,2) в масштабированной версии = (3,3) :( 8,8)
- 2x2 пикселя = 25% площади масштабированной версии
- 6x6 пикселей = 25% площади оригинальной версии
Если бы нужно было просто умножить на те же коэффициенты масштабирования, это быgive (3,3) :( 6,6).
OriginalTop = INT (ScaledTop * YScalingFactor);
OriginalLeft = INT (ScaledLeft * XScalingFactor);
OriginalBottom = INT ((ScaledBottom + 1) * YScalingFactor) - 1;
OriginalRight = INT ((ScaledRight + 1) * XScalingFactor) - 1;
РЕДАКТИРОВАТЬ :
Лучший способ объяснить, что я пытаюсь сказать, - нарисовать изображение.И я сосу в ASCII Art.Итак, вот еще одна попытка со словами.
Пиксель не точка.Это маленький прямоугольник в своем собственном правом.
Когда вы используете пиксель для представления левого верхнего угла прямоугольника, вы включаете область от самой верхней левой точки пикселя.
Когда вы используете пиксель для представления нижнего правого прямоугольника, вы включаете область вплоть до нижнего правого самой точки пикселя.
При повторном использовании примера (12x12) => (4x4) каждый масштабированный пиксель представляет собой весь набор пикселей 3x3 в оригинале.Говоря о верхнем левом углу, вы выбираете верхний левый пиксель группы пикселей 3х3 в оригинале.А если говорить о правом нижнем углу, вы выбираете нижний правый размер группы пикселей 3x3 в оригинале.
РЕДАКТИРОВАТЬ : использовать только целые числа.
NewTop = (( OldTop ) * NewHeight / OldHeight);
NewLeft = (( OldLeft ) * NewWidth / OldWidth );
NewBottom = ((OldBottom + 1) * NewHeight / OldHeight) - 1;
NewRight = ((OldRight + 1) * NewWidth / OldWidth ) - 1;
Единственное соображение - убедиться, что вы не переполнили свой тип данных после умножения.Но с изображениями вы не будете, если это не адское изображение.