ソース長方形とデスティネーション長方形があります。宛先の四角形内に収まり、元のアスペクト比を維持しながら、ソースをスケーリングできる最大のスケールを見つける必要があります。
グーグルはそれを行うための one 方法を見つけましたが、それがすべてのケースで機能するかどうかはわかりません。これが私の自家製のソリューションです:
msrc
およびmdest
が得られます。msrc < mdst
、宛先widthに合わせてソースwidthをスケールします(そしてスケールします)同じ比率で高さ)この問題の他の可能な解決策を探しています。私のアルゴリズムがすべてのケースで機能するかどうかさえわかりません!
scale = min( dst.width/src.width, dst.height/src.height)
これはあなたのアプローチですが、よりきれいに書かれています。
別のオプションは、最大幅にスケーリングしてから、スケーリングされた高さが最大許容高さより大きいかどうかを確認し、そうであれば高さでスケーリングする(またはその逆):
scale = (dst.width / src.width);
if (src.height * scale > dst.height)
scale = dst.height / src.height;
このソリューションは、短く、速く、理解しやすいと思います。
すべての次元がゼロ以外の場合、次のコードを使用します(コードは基本的にあなたのコードと一致します)。
scaleFactor = (outerWidth / outerHeight > innerWidth / innerHeight)
? outerHeight / innerHeight
: outerWidth / innerWidth
これを変更して、必要に応じて任意の次元をゼロにすることもできます。
destWidth / srcWidth
とdestHeight / srcHeight
の小さい方を計算する編集もちろん、これはメソッドと同じですが、数式の一部が移動します。私のopinionは、これは意味的に明確であるということですが、それだけです-意見です。
他の回答には、sourceWidthまたはsourceHeightのいずれかがゼロになると、ゼロ除算例外が生成されるリスクがあります。これを防ぐには、比較を数学的に等価な複数の式に書き直す必要があります。また、無限スケールのシナリオをキャッチするための追加のEdge条件。
スケール以外にも、ターゲットの四角形の寸法が本当に欲しかったので、ここでスケールの計算とターゲットの四角形の計算を提供します。
無限のエッジ条件のため、ターゲットの四角形はより堅牢/便利になると思います:
if (sourceWidth == 0 && sourceHeight == 0) {
// scale = Infinity;
outputWidth = 0;
outputHeight = 0;
outputX = destWidth / 2;
outputY = destHeight / 2;
} else if (destWidth * sourceHeight > destHeight * sourceWidth) {
scale = destHeight / sourceHeight;
outputWidth = sourceWidth * destHeight / sourceHeight;
outputHeight = destHeight;
outputX = (destWidth - outputWidth) / 2;
outputY = 0;
} else {
scale = destWidth / sourceWidth;
outputWidth = destWidth;
outputHeight = sourceHeight * destWidth / sourceWidth;
outputX = 0;
outputY = (destHeight - outputHeight) / 2;
}