Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make an image fit in a rectangle

Tags:

java

image

max

If I have an image of which I know the height and the width, how can I fit it in a rectangle with the biggest possible size without stretching the image.

Pseudo code is enough (but I'm going to use this in Java).

Thanks.


So, based on the answer, I wrote this: but it doesn't work. What do I do wrong?

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);
}
like image 910
Martijn Courteaux Avatar asked Apr 29 '10 19:04

Martijn Courteaux


3 Answers

This will not affect your aspect ration and will fit exactly on one side and not overshoot on the other side.

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);
}
like image 60
ucMedia Avatar answered Nov 14 '22 02:11

ucMedia


Here is my two cents:

/**
 * 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;
}
like image 38
Sileria Avatar answered Nov 14 '22 01:11

Sileria


Determine the aspect ratio of both (height divided by width, say, so tall, skinny rectangles have an aspect ratio > 1).

If your rectangle's aspect ratio is greater than that of your image, then scale the image uniformly based on the widths (rectangle width / image width).

If your rectangle's aspect ratio is less than that of your image, then scale the image uniformly based on the heights (rectangle height / image height).

like image 16
John Avatar answered Nov 14 '22 02:11

John