web-dev-qa-db-ja.com

数学/アルゴリズム画像を画面に合わせるアスペクト比を維持

既知のサイズの画像を取得し、2つの画面寸法のいずれかに合わせるために、数学/アルゴリズムの助けが必要です。

720 x 480または1280 x 1024。

画像の寸法はXMLファイルから取得されますが、これらの寸法はWebの寸法ですが、Webの寸法よりも解像度が高い場合と低い場合があるXMLから選択した画像も取得します。

私が欲しいのは、Web寸法のアスペクト比を使用して、高解像度の画像をHD(1280x720)画面に表示するか、ユーザーがSD画面(720x480)にある場合はその画面に画像を表示することです。

これに役立つが優先順位が低い他のことは、画像の解像度がSD画面よりも両方の次元で小さいことがわかっている場合です(この場合、私が知っているのはWeb次元と水平次元のみです)画像ファイルの)、その画面に実際のサイズで表示します。

それが十分に明確であることを願っています。

ありがとう!

42
alphablender

一般的なもの:

画像データ:(w、h)そしてrを定義する = w /時間
画面解像度:(ws、hs)そしてrを定義するs = ws /時間s

スケーリングされた画像の寸法:

rs > ri ? (wi * hs/hi, hs) : (ws, hi * ws/wi)

だから例えば:

         20
|------------------|
    10
|---------|

--------------------     ---   ---
|         |        |      | 7   |
|         |        |      |     | 10
|----------        |     ---    |
|                  |            |
--------------------           ---

ws = 20
hs = 10
wi = 10
hi = 7

20/10 > 10/7 ==> (wi * hs/hi, hs) = (10 * 10/7, 10) = (100/7, 10) ~ (14.3, 10)

ご覧のとおり、高さは画面の高さですが、縦横比は14.3/10 ~ 10/7

[〜#〜]更新[〜#〜]

次のように画像を中央に配置します。

呼び出し(w新着、h新着)新しい次元。

top = (hs - hnew)/2
left = (ws - wnew)/2
147
davin

ここでは、単純なCです。

両方の座標を、返された倍率でスケーリングしたいとします。

/*画面内の長方形の場合、引き伸ばしたり押しつぶしたりせずに長方形
をスケーリングできるようにするスケール係数を取得します。 */
 float 
 aspect_correct_scale_for_rect(const float screen [2]、const float rect [2])
 {
 float screenAspect = screen [0]/screen [ 1]; 
 float rectAspect = rect [0]/rect [1]; 
 
 float scaleFactor; 
 if(screenAspect> rectAspect)
 scaleFactor = screen [1]/rect [1]; 
 else 
 scaleFactor = screen [0]/rect [0]; 
 
 return scaleFactor; 
} 
 
11
Michael Labbé

私は受け入れられた答えを理解し、それが機能しますが、次の方法が「最適」のために、より単純で簡潔であることが常にわかりました。

// prep
let maxWidth = 190,
    maxHeight = 150;
let imgWidth = photo.width,
    imgHeight = photo.height;

// calc
let widthRatio = maxWidth / imgWidth,
    heightRatio = maxHeight / imgHeight;
let bestRatio = Math.min(widthRatio, heightRatio);

// output
let newWidth = imgWidth * bestRatio,
    newHeight = imgHeight * bestRatio;
6
pstanton

レターボックスまたは画面に合わせるとアスペクト比を修正

私は最近、iOSでこの正確な問題を処理する方法を書きました。スケーリングを行うために固有行列ライブラリを使用していますが、原理(スケーリング係数)は行列がなくても同じです。

Eigen::Matrix4x4f aspectRatioCorrection(bool fillScreen, const Eigen::Vector2f &screenSize, const Eigen::Vector2f &imageSize)
{
    Eigen::Matrix4x4f scalingMatrix(Eigen::Matrix4x4f::Identity());

    float screenWidth = screenSize.x();
    float screenHeight = screenSize.y();
    float screenAspectRatio = screenWidth / screenHeight;
    float imageWidth = imageSize.x();
    float imageHeight = imageSize.y();
    float imageAspectRatio = imageWidth / imageHeight;

    float scalingFactor;
    if (fillScreen) {
        if (screenAspectRatio > imageAspectRatio) {
            scalingFactor = screenWidth / imageWidth;
        } else {
            scalingFactor = screenHeight / imageHeight;
        }
    } else {
        if (screenAspectRatio > imageAspectRatio) {
            scalingFactor =  screenHeight / imageHeight;
        } else {
            scalingFactor = screenWidth / imageWidth;
        }
    }

    scalingMatrix(0, 0) = scalingFactor;
    scalingMatrix(1, 1) = scalingFactor;

    return scalingMatrix;
}