Поместить изображение в прямоугольник

Если у меня есть изображение, о котором я знаю высоту и ширину, как я могу поместить его в прямоугольник с максимально возможным размером, не растягивая изображение.

псевдо-кода достаточно (но я собираюсь использовать это в Java).

спасибо.


Итак, основываясь на ответе, я написал следующее: Но это не работает. Что я делаю не так?

double imageRatio = bi.getHeight() / bi.getWidth();
double rectRatio = getHeight() / getWidth();
if (imageRatio < rectRatio)
{
    // based on the widths
    double scale = getWidth() / bi.getWidth();
    g.drawImage(bi, 0, 0, (int) (bi.getWidth() * scale), (int) (bi.getHeight() * scale), this);
}
if (rectRatio < imageRatio)
{
    // based on the height
    double scale = getHeight() / bi.getHeight();
    g.drawImage(bi, 0, 0 , (int) (bi.getWidth() * scale), (int) (bi.getHeight() * scale), this);
}

3 ответов


определите соотношение сторон обоих (высота, деленная на ширину, скажем, так что высокие, тощие прямоугольники имеют соотношение сторон > 1).

Если соотношение сторон вашего прямоугольника больше, чем у вашего изображения, то масштабируйте изображение равномерно на основе ширины (ширина прямоугольника / ширина изображения).

Если соотношение сторон вашего прямоугольника меньше, чем у вашего изображения, то масштабируйте изображение равномерно на основе высот (высота прямоугольника / высота изображения).


вот мои два цента:

/**
 * Calculate the bounds of an image to fit inside a view after scaling and keeping the aspect ratio.
 * @param vw container view width
 * @param vh container view height
 * @param iw image width
 * @param ih image height
 * @param neverScaleUp if <code>true</code> then it will scale images down but never up when fiting
 * @param out Rect that is provided to receive the result. If <code>null</code> then a new rect will be created
 * @return Same rect object that was provided to the method or a new one if <code>out</code> was <code>null</code>
 */
private static Rect calcCenter (int vw, int vh, int iw, int ih, boolean neverScaleUp, Rect out) {

    double scale = Math.min( (double)vw/(double)iw, (double)vh/(double)ih );

    int h = (int)(!neverScaleUp || scale<1.0 ? scale * ih : ih);
    int w = (int)(!neverScaleUp || scale<1.0 ? scale * iw : iw);
    int x = ((vw - w)>>1);
    int y = ((vh - h)>>1);

    if (out == null)
        out = new Rect( x, y, x + w, y + h );
    else
        out.set( x, y, x + w, y + h );

    return out;
}

Это не повлияет на ваш рацион аспекта и поместится точно на одной стороне и не перескочит на другой стороне.

public static Rect getScaled(int imgWidth, int imgHeight, int boundaryWidth, int boundaryHeight) {

    int original_width = imgWidth;
    int original_height = imgHeight;
    int bound_width = boundaryWidth;
    int bound_height = boundaryHeight;
    int new_width = original_width;
    int new_height = original_height;

    // first check if we need to scale width
    if (original_width > bound_width) {
        //scale width to fit
        new_width = bound_width;
        //scale height to maintain aspect ratio
        new_height = (new_width * original_height) / original_width;
    }

    // then check if we need to scale even with the new height
    if (new_height > bound_height) {
        //scale height to fit instead
        new_height = bound_height;
        //scale width to maintain aspect ratio
        new_width = (new_height * original_width) / original_height;
    }

    return new Rect(0,0,new_width, new_height);
}