views:

351

answers:

4

The problem here is I have a display window of size x by y, and I need to display an image inside the window without any scrolling, and to maintain the aspect ratio of 4:3. I have the following snippet of code:

// Lock the current height, calculate new width of the canvas and scale the viewport.
// get width of the movie canvas
qreal width = canvas_->width();

// Find the height of the video
qreal height = (width/4.0) * 3;

// find original width and height for video to calculate scaling factor
qreal videoWidth = movieData_->GetWidth();
qreal videoHeight = movieData_->GetHeight();

// calculate scaling factor
qreal scaleFactorWidth = width/videoWidth;
qreal scaleFactorHeight = height/videoHeight;

Of course, by using either the height, or the width as the 'anchor', one way or other the new image will cause scrolling (assuming the original image is larger than the window in the first place). How do I find a dimension of aspect ratio 4:3 which fits within a predetermined size?

Edit I would need to pass in a scale factor for both x and y to do the scaling

canvas_->scale(scaleFactorWidth, scaleFactorHeight);
+5  A: 

Just take the minimum of the both calculated values:

scale = min(scaleFactorWidth, scaleFactorHeight)

or (if you want outer-fit)

scale = max(scaleFactorWidth, scaleFactorHeight)
Marcel J.
I'm not sure I understand; I need a scale factor for both x and y.
Extrakun
@Extrakun, the scale factor will be the same for both, otherwise you'll end up with an out-of-proportion image.
Dominic Rodger
Right, scale_x = scale_y = scale. This is the only way to maintain the aspect ratio.
Marcel J.
+1  A: 

Find the largest of the two values width, w and height h. Say your maximum width x height is 100 x 80. Note that 100/80 = 1.25.

Case 1: If w/h > 1.25, then divide w by 100 to get the ratio of your original size to the new size. Then multiply h by that ratio.

Case 2: Otherwise, then divide h by 80 to get the ratio of your original size to the new size. Then multiply w by that ratio.

Dominic Rodger
Nope, it's not a square. I guess I may just have keep decreasing the width I want till I get a height that fits within the predetermined size?
Extrakun
@Extrakun - see my edit.
Dominic Rodger
+1  A: 

Here's an ActionScript version of what you ask (resize while maintaining aspect ratio)... shouldn't be too hard to port to whatever:

    private static function resizeTo(dispObj:DisplayObject, width:Number, height:Number) : void
    {
        var ar:Number = width / height;
        var dispObjAr:Number = dispObj.width/dispObj.height;
        if (ar < dispObjAr)
        {
            dispObj.width = width;
            dispObj.height = width / dispObjAr;
        }
        else
        {
            dispObj.height = height;
            dispObj.width = height * dispObjAr;
        }
        return;
    }

EDIT: In order to maintain 4:3 the source images would need to be 4:3

spender
+1  A: 
    struct dimensions resize_to_fit_in(struct dimensions a, struct dimensions b) {
        double wf, hf, f;
        struct dimensions out;

        wf = (double) b.w / a.w;
        hf = (double) b.h / a.h;

        if (wf > hf)
                f = hf;
        else
                f = wf;

        out.w = a.w * f;
        out.h = a.h * f;

        return out;
}

An here is a C version where the returned dimension will be a dimension 'a' fitted in dimension 'b' without loosing aspect ratio.

Thanks for keeping in mind that I need a scaling factor :)
Extrakun