Image assets

You can use images as assets that are packaged with your app. These types of images might include backgrounds, borders, icons, or other UI-related images. Images stored in the app's assets directory are packaged with the app binary at compile time, so that the app can access them quickly. Even though the images are loaded asynchronously, they should load successfully in a short period of time.

A set of layered images.

Loading image assets

Images, like other assets, should be placed in the assets folder of your Cascades project. As a best practice, you should create an images folder in the assets folder and store your images there.

To load an image asset, you can use an absolute path or a relative path. Both methods load the image asynchronously, so the image might show up after other UI elements appear. To use an absolute path, you must specify the asset:/// prefix followed by the path to the image from the assets folder, and the name of the image including the file name extension.

Always remember to use three slashes in the asset:/// prefix.

The asset:/// prefix resolves to a URL that points to the assets folder in your app. You can also use a path that's relative to the location of the .qml file that's loading the image.

Let's say that you have an image called myimage.png that you've placed in the assets/images folder in your project. Here's how you can load the image using both absolute and relative paths:

// Absolute path
ImageView {
    imageSource: "asset:///images/myimage.png"   
}

// Relative path
ImageView {
    imageSource: "images/myimage.png"   
}

The relative path for loading an image in C++ is different from QML because the binary for the app is stored in the parent folder of the assets folder.

// Absolute path
Image image = Image(QUrl("asset:///images/myimage.png"));

// Relative path
Image image = Image(QUrl("assets/images/myimage.png"));

Not applicable

Nine-slice scaling

Nine-slice scaling is a technique that is typically used for background and border images. It allows an image to scale to virtually any size while keeping its corners sharp and borders uniform. Using nine-slice scaling can help minimize the size and number of image assets that you bundle with your app.

For example, if you're developing a chat app, you need a standard background image for messages. The image below on the left represents such a background image. To support large amounts of text, you need to scale the image vertically to fit more text in the center of the background image. However, without the nine-slice scaling technique, the borders of the image get scaled as well, as shown below in the image on the right. As the image scales in height, the top and bottom borders become thicker than the border on the sides, which causes the corners to stretch. As a best practice, you want the borders and corners to stay uniform no matter what size the image is scaled to. To ensure that your image borders and corners are not scaled, you must specify nine-slice margins for the image.


An image with uniform borders.


An image with scaled borders.

Specifying nine-slice margins

Nine-slice margins can be specified in a metadata file with the same name as the image but with an .amd extension (the metadata file must be placed in the same folder as the image assets). When defining the nine-slice margins, you must use the following format:

#RimCascadesAssetMetaData version=1.0
source: "image.png"
sliceMargins: 15 15 15 15

The source property contains the name of the image that you want to perform nine-slice scaling on. The sliceMargins property indicates the number of pixels that need to be sliced off each side of the image (in the order of left, right, top, and bottom). By specifying the slice margins, the image is sliced into nine parts:


A grid showing an image sliced into nine parts.

In the image above, using the nine-slice scaling technique prevents the corners (1,3,7,9) from being scaled. Similarly, the top and bottom borders (2,8) can be scaled only in the horizontal direction and the borders on the sides (4,6) can be scaled only in the vertical direction; the thickness of the borders is never altered. The center part of the image (5) can be scaled in any direction. Because you want to scale the image vertically, the center part of the image and both of the side borders (4,5,6) are scaled. The resulting image looks like this image:


A scaled image with uniform borders.

Loading images

When loading an image that uses nine-slice scaling, you must load the .amd file instead of the image itself. Otherwise, the nine-slice margins are ignored. In addition, make sure that you load the file as an asset.

ImageView {
    imageSource: "asset:///nine_sliced_background.amd"
    preferredWidth: 500
    preferredHeight: 500
}
ImageView *nineSliceImage = ImageView::create(
    "asset:///images/nine_sliced_background.amd");

Not applicable

Tools

Cascades Exporter lets you specify nine-slice margins for your images so that the settings can be imported directly into QML. For more information, see Tutorial: Explore Cascades Exporter.

The QML Editing perspective in the Momentics IDE for BlackBerry lets you view your images and set the nine-slice margins directly in the editor. For more information, see Image viewer.

Image colorization 10.3

Image colorization allows you to apply a color filter to an image during runtime to minimize the number of image variants that you need to package with your app. All images can have a color filter applied, and images that you use as action item icons can be colorized automatically according to the current theme. This approach can be useful if you create multiple themes for your app. For more information about themes, see Themes.

As a best practice for colorization, you should create an .amd (asset metadata) file for the image that you want to colorize. An .amd file is placed in the same folder as your image asset and contains metadata for the image.

In the .amd file, you can use the type property to enable or disable colorization. Setting the type to template enables colorization of an image. Using the template type, Cascades accepts colorization of images using the filterColor property and also tries to colorize images that are used as action item icons according to the device theme. A type of normal overrides the framework and uses the original image, even if a filterColor is applied. For more information about overriding the framework, see Action item images.

The following code sample shows the structure of an .amd file for an image named myImage.png with a type of template:

#RimCascadesAssetMetaData version=1.1
type: template
source: "myImage.png"

To use colorization, the #RimCascadesAssetMetaData version must be set to 1.1.

A color filter can then be applied to an image using the filterColor property, which recolors the pixels in an image with the specified color. White pixels are recolored to the color that you specify, black pixels remain black, and color pixels appear as a new color representing a combination of the original color and the filter color.

Image colorization supports predefined color constants, as well as custom colors you specify using Color.create(). For more information on supported colors, see the Color API reference.

The following code sample applies a filterColor derived from a hex value to an image:

import bb.cascades 1.3

Page {
    Container {
        ImageView {
            imageSource: "asset:///images/myImage.amd"
            // This colorizes the image with 
            // the provided color. 
            filterColor: Color.create("#ff2c2c")
        }

    }
}

Here is how to apply a filterColor derived from a 32-bit ARGB value:

#include <bb/cascades/Application>
#include <bb/cascades/Page>
#include <bb/cascades/ImageView>
#include <bb/cascades/Color>
#include <bb/cascades/Container>

using namespace bb::cascades;

ApplicationUI::ApplicationUI(bb::cascades::Application *app) :
        QObject(app)
{
    // Create a Container and set the layout
    Page *page = new Page();

    Container *root = Container::create();

    ImageView *myImageView = ImageView::create()
            .image(Image(QUrl("asset:///images/myImage.amd")))
            .filterColor(Color::fromARGB(0xffff2c2c));

    root->add(myImageView);
    page->setContent(root);
    app->setScene(page);
}

Not applicable

The following image demonstrates the difference between the standard image appearance and the image appearance with a filter color applied using the code sample above:


Screen shot showing the difference between the standard image and an image with a filter color applied.

Related resources

Last modified: 2015-04-16



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus