3. Maintaining the aspect ratio when loading an image into a texture
Prev | Chapter 4. Textures | Next

## 3. Maintaining the aspect ratio when loading an image into a texture

### 3.1. Problem

You want want to load an image into a texture and scale it, while retaining the underlying image's aspect ratio.

### 3.2. Solution

Set the texture to keep the aspect ratio of the underlying image (so it doesn't distort when it's scaled); use the actor's request-mode property to set the correct geometry management (see the discussion section); then resize the texture along one dimension (height or width). Now, when an image is loaded into the texture, the image is scaled to fit the set height or width; the other dimension is automatically scaled by the same factor so the image fits the texture:

    ClutterActor *texture;
    texture = clutter_texture_new ();

    clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (texture), TRUE);

    /*
     * this setting means the height of the scaled image is based on its width;
     * it's not strictly necessary to set this, as this is the default
     */
    clutter_actor_set_request_mode (texture, CLUTTER_REQUEST_HEIGHT_FOR_WIDTH);

    /* set the width, which causes height to be scaled by the same factor */
    clutter_actor_set_width (texture, 300);

    clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
                                   "/path/to/image.jpg",
                                   NULL);

### 3.3. Discussion

The request-mode for an actor determines how geometry requisition is performed; in this case, this includes how scaling is applied if you change the actor's width or height. There are two possible values for request-mode:

1. If set to `CLUTTER_REQUEST_HEIGHT_FOR_WIDTH` (the default), changing the width causes the height to be scaled by the same factor as the width.

2. If set to `CLUTTER_REQUEST_WIDTH_FOR_HEIGHT`, changing the height causes the width to be scaled by the same factor as the height.

In the example above, the texture is set to keep its aspect ratio then fixed to a width of 300 pixels; the request-mode is set to `CLUTTER_REQUEST_HEIGHT_FOR_WIDTH`. If a standard, photo-sized image in landscape orientation were loaded into it (2848 pixels wide x 2136 high), it would be scaled down to 300 pixels wide; then, its height would be scaled by the same factor as the width (i.e. scaled down to 225 pixels).

With request-mode set to `CLUTTER_REQUEST_WIDTH_FOR_HEIGHT`, you would get the same effect by setting the height first; then, computation of the width for the scaled image would be based on the scaling factor applied to its height instead.

You can work out which side of the source image is longest using `clutter_texture_base_size()` to get its width and height. This can be useful when trying to scale images with different orientations to fit into uniform rows or columns:

    gint width;
    gint height;

    clutter_texture_get_base_size (CLUTTER_TEXTURE (texture), &width, &height);

### Note

If you explicitly set the size (both width and height) of a texture with `clutter_actor_set_size()` (or with `clutter_actor_set_width()` and `clutter_actor_set_height()`), any image loaded into the texture is automatically stretched/shrunk to fit the texture. This is the case regardless of any other settings (like whether to keep aspect ratio).

### Note

Since a texture can scale down its contents, its minimum preferred size is 0.

Prev | Up | Next
2. Drawing 2D graphics onto a texture | Home | 4. Loading image data into a texture