Image

Since: BlackBerry 10.0.0

#include <bb/cascades/Image>

An image resource, the source of which might not be known.

Images can come from a number of different sources, the most common of which is as an asset that is packaged with the application. This is the type of image that is commonly used in the user interface.

One of the benefits of packaging an image with the application is that it allows the tool to verify the images and optimize them for the devices they are targeting. Because they are packaged with the application, it should be assumed that they are instantly available, and should never fail to load. If an incorrect name is provided when an asset is created, an null image is returned.

As long as the image is placed in the assets folder in your project, you can refer to it using a relative path to the assets directory (asset:///) followed by the file name. For example:

Image imageAsset = Image(QUrl("asset:///myasset.png"));

The absolute path to the assets directory is file:///app_working_directory/app/native.

Images outside the assets directory

Each application has access to its own working directory in the file system. The working directory is where application is started, and is also known as the "current directory" and the "sandbox."

Within the application working directory, there are a number of folders that your application has access to. The data folder (otherwise known as the "home" directory) contains your application's private data. Here's an example of how to use a path relative to the application working directory to load an image from the home directory:

Image image = Image(QUrl("file://" + QDir::homePath() + "/image2.png"));

Your application can also access folders outside the application working directory, in a shared folder. Here's an example of how to load an image from the shared/camera folder (provided that you set the appropriate permissions for it in your bar-descriptor.xml file). In this example, an absolute path is used:

Image image = Image(QUrl("file:///accounts/1000/shared/camera/camera0001.jpg"));

Images in QML

Here are some examples of how to use an Image in QML:

ImageView {
    imageSource: "asset:///myAsset.png"
}

Button {
    imageSource: "images/button.png"
}
   
ImageTracker {
    id: anImage
    imageSource: "asset:///myAsset.png"
}
   
ImageView {
    image: anImage.image
}

Loading an image

When dealing with images that are not assets (i.e. not packaged with the application), it should be assumed that the image might take a considerable time to load, or may not load at all. To account for this, an Image goes through a series of states indicating when the image is loaded and if an error occurred. The state of an image and information about its size are accessible through ImageTracker, which encapsulates the asynchronous parts of the Image.

Here's an example showing how to load an image and display it when it is successfully loaded, in C++:

void MyApp::setup() {
    mImageView = new ImageView();
    mImageTracker = new ImageTracker(QUrl("assets/image.png"));

    bool result = connect(mImageTracker,
        SIGNAL(stateChanged(bb::cascades::ResourceTracker::State)),
        this,
        SLOT(onStateChanged(bb::cascades::ResourceTracker::State)));

    Q_ASSERT(result);
    Q_UNUSED(result);
  
    // ...
}

void MyApp::onStateChanged(ResourceTracker::State state)
{
    if(state == ResourceTracker::Loaded)
    {
        mImageView->setImage(mImageTracker->image());
    }
}

Here's an example in QML showing how to load an image and display it when it is successfully loaded:

ImageView {
    id: myImageView
    attachedObjects: [
        ImageTracker {
            id: tracker
            imageSource: "images/image.png"
       
            onStateChanged: { 
                if (state == ResourceTracker.Loaded)
                {
                    myImageView.image = tracker.image
                }
            }
        }
    ]
}

Creating images from data

It's also possible to create images from raw pixel data using ImageData::fromPixels(). In order to create the image from a set of data, all you need to specify is the source of the data, the format of the pixel data (as specified by PixelFormat), the width and height of the image, and the number of bytes per line in the data source.

Here's an example of how to create an image from a random set of pixel data. The pixel format used is RGBX.

int data[8][8];
for (int y=0;y<8;y++) {
    for (int x=0;x<8;x++) {
        data[x][y] = rand();
    }
}
Image m_image = bb::ImageData::fromPixels((
        const unsigned char*)data, 
        bb::PixelFormat::RGBX, 
        8, 8, 8*4);

Nine-slice scaling

Image resources can be specified to have nine-slice margins, which can be retrieved using the nineSliceMargin*() methods. A nine-sliced image will, when displayed, be stretched according to nine-slice rules instead of being simply scaled.

In the animated image above,
  • the four corners (1,3,7,9) are not scaled,

  • the left and right 'margins' (4,6) are scaled only vertically (i.e., their width is not touched),

  • and the top and bottom 'margins' (2,8) are scaled only horizontally (i.e., their height is not touched). The center area (5) is the only one that's scaled both horizontally and vertically.

To specify that the image is nine-sliced place a metadata file with the same name but ".amd" extension next to the image (i.e., in the same directory) and specify the nine-slices with the following format:
sliceMargins: l r t b
Where "l" is the left slice margin, "r" is the right margin, "t" is the top margin and "b" is the bottom margin.
With reference to the animated image above:
  • the 'l' parameter is the horizontal size of the areas 1,4, and 7

  • the 'r' parameter is the horizontal size of the areas 3,6, and 9

  • the 't' parameter is the vertical size of the areas 1,2, and 3

  • the 'b' parameter is the vertical size of the areas 7,8, and 9

For example, if there's a nine-sliced image called "nine_sliced_background.png", the metadata file must be called "nine_sliced_background.amd" and placed in the same directory as the image. The contents of the file might look something like this depending on the nine-slice margin values for your image:
#RimCascadesAssetMetaData version=1.0
source: "nine_sliced_background.png"
sliceMargins: 63 62 51 123

In your application, you simply reference the .amd file instead of the image and whenever it's scaled the image will maintain its edges.

ImageView {
    imageSource: "asset:///nine_sliced_background.amd"
    preferredWidth: 500
    preferredHeight: 500
}

In the metadata file, lines beginning with '#' are ignored, and can be used for comments.

Tiling images

Using the ImagePaint (C++) and ImagePaintDefinition (QML) classes you can use images as background fill for a container. The RepeatPattern class determines how/if the image is tiled on the container.

In order for an image to be tileable, it must have the "repeatable: true|false" property set in the asset metadata file. This is the same .amd file that can contain nine-slicing attributes, however the tiling of nine-sliced images is not currently supported.


Overview

Inheritance

bb::cascades::Resource
bb::cascades::Image

Public Functions Index

Image ()
Image (const QUrl &source)
Image (const char *source)
Image (const Image &other)
Image (const ImageData &imageData)
Image (const QByteArray &encodedImageData)
virtual ~Image ()
intnineSliceMarginBottom () const
intnineSliceMarginLeft () const
intnineSliceMarginRight () const
intnineSliceMarginTop () const
Image &operator= (const Image &other)
QUrlsource () const
boolisNull () const Inherited

Public Functions

Image ()

Constructs a null image.

Image image();
Since:

BlackBerry 10.0.0

Image (

Constructs an image from the given URL.

Image image(QUrl("images/a_image.png"));

Since it is not known at the time of creation whether the image will load successfully, the creation process cannot fail. In other words, this constructor will always create a non-null image. To check for errors, use ImageTracker.

If the image is loaded from the asset collection it will fail at once and return an null image if the asset is not found.

Here's an example of how to load an image from the asset collection.
Image img(QUrl("asset:///myAsset.png"));
Parameters
source

The relative path to the image.

Since:

BlackBerry 10.0.0

Image (
  • const char *source)

Constructs an image from the given URL.

Image image("images/a_image.png");

Since it is not known at the time of creation whether the image will load successfully, the creation process cannot fail. In other words, this constructor will always create a non-null image. To check for errors, use ImageTracker.

If the image is loaded from the asset collection it will fail at once and return an null image if the asset is not found.

Here's an example of how to load an image from the asset collection.
Image img("asset:///myAsset.png");
Parameters
source

The relative path to the image.

Since:

BlackBerry 10.0.0

Image (

Constructs a copy of another Image.

Image a("images/a_image.png");
Image b(a);
Parameters
other

The Image to be copied.

Since:

BlackBerry 10.0.0

Image (

Creates an image based on already decoded pixel data.

The caller is responsible for creating the bb::ImageData instance.

Only bb::PixelFormat::RGBA_Premultiplied and bb::PixelFormat::RGBX formats are supported at the moment. If ImageData with a different format is passed it will be ignored and a warning will be printed out.

Note:

Once an Image is created from a particular instance of bb::ImageData updating the data contained by bb::ImageData will have no effect on the contents of the Image since the data is copied on creation.

ImageData based images are different from other images in that they don't report state changes and they are not trackable through ImageTracker. They are also not available from QML.
#include <bb/ImageData>

// create ImageData from pixel data stored in pBuffer
bb::ImageData imageData =
    bb::ImageData::fromPixels(pBuffer, 
                              bb::PixelFormat::RGBA_Premultiplied,
                              100, 100, 400);
// pBuffer can be freed now if needed as ImageData::fromPixels made a copy

// create an Image from the data
Image image( imageData );

// allocate pixel data by creating an ImageData, modify and then create an image
bb::ImageData imageData1(bb::PixelFormat::RGBX, 100, 100);
unsigned char* pixels = imageData1.pixels();
// modify the pixels

// now create an image from the data
Image image( imageData1 );

// imageData, imageData1 are implicitly shared, data will be freed when
// there are no more references to it
Parameters
imageData

The ImageData object to construct the image from.

See also:

bb::ImageData

Since:

BlackBerry 10.0.0

Image (

Creates an image based on a buffer containing encoded image data.

The user provided QByteArray should contain the raw data of a png, jpeg or gif file.

Note:

Once an Image is created from a particular QByteArray, updating the data contained by the QByteArray will have no effect on the contents of the Image since the data is copied on creation.

QByteArray based images are different from other images in that they don't report state changes and they are not trackable through ImageTracker. They are also not available from QML.
// read file into QByteArray
QFile file("myfile.png");
file.open(QIODevice::ReadOnly);
QByteArray data = file.readAll();

Image image(data);
Parameters
encodedImageData

The encoded image data to construct the image from.

Since:

BlackBerry 10.0.0

virtual~Image ()

Destructor.

int nineSliceMarginBottom ()

Returns the bottom nine-slice margin of the current image.

If the image is empty, or if the image is not a nine-slice image, all nine-slice margins are 0.

Return:

The bottom nine-slice margin of the current image, or 0 if the image is empty, or not a nine-slice image.

Since:

BlackBerry 10.0.0

int nineSliceMarginLeft ()

Returns the left nine-slice margin of the current image.

If the image is empty, or if the image is not a nine-slice image, all nine-slice margins are 0.

Return:

The left nine-slice margin of the current image, or 0 if the image is empty, or not a nine-slice image.

Since:

BlackBerry 10.0.0

int nineSliceMarginRight ()

Returns the right nine-slice margin of the current image.

If the image is empty, or if the image is not a nine-slice image, all nine-slice margins are 0.

Return:

The right nine-slice margin of the current image, or 0 if the image is empty, or not a nine-slice image.

Since:

BlackBerry 10.0.0

int nineSliceMarginTop ()

Returns the top nine-slice margin of the current image.

If the image is empty, or if the image is not a nine-slice image, all nine-slice margins are 0.

Return:

The top nine-slice margin of the current image, or 0 if the image is empty, or not a nine-slice image.

Since:

BlackBerry 10.0.0

Image & operator= (

Assigns another Image to this Image.

Parameters
other

The image to be assigned to this image.

Return:

A reference to the image.

Since:

BlackBerry 10.0.0

QUrl source ()

Returns the image source.

Return:

The image source.

Since:

BlackBerry 10.0.0

bool isNull ()Inherited

Returns true if the resource is null.

Return:

true if this resource is null, false otherwise.

Since:

BlackBerry 10.0.0

Last modified: 2014-03-13

comments powered by Disqus