C/C++ Guides

Home

Downloading Images from the Internet

Often when using images in MoSync, then the images are available to you as a developer, and you can package them with your application, as described in the tutorial 'Adding Resources to a Project'.  However, there will be many scenarios where you want to show a picture you've not been able to package.  This may be because there are  too many pictures, or you are responding to user input.  An image search of Google or Bing would be an example of this, there you cannot possibly know what the user is going to search for, nor could you package the images in advance.

The ImageDownloader

There is a class which has been specifically created to remove some of the complexities of downloading images from the Web.  The ImageDownloader class is defined in MAUtil/Downloader.h, and will create an image resource for you.  To use the ImageDownloader, you will need to create a new class which inherits from DownloadListener.  By doing this, your program will be informed when the image has downloaded and is ready to display.

/**
 * @file DownloadImage.cpp
 *
 * This program downloads and displays an Image file from the Internet.
 *
 * Todo: You need to goto Project -> Properties -> Build Settings and
 * add MAUtil.lib, MAUI.lib libraries in Additional Libraries.
 *
 * @author Sam Pickard, Naveed Asif
 */

#include <MAUtil/Moblet.h>
#include <MAUI/Screen.h>
#include <MAUI/Image.h>
#include <MAUtil/Downloader.h>
#include <conprint.h>

using namespace MAUtil;
using namespace MAUI;

/*
 * Class that downloads an image file from
 * the Internet.
 */
class MyScreen :
    public Screen,
    DownloadListener
{
public:

    MyScreen()
    {
        // Message: Starting application.
        lprintfln("Starting application");

        // A new instance of ImageDownloader is created.
        mImageDownloader = new ImageDownloader();
        mImageDownloader->addDownloadListener(this);
        mImageResource = maCreatePlaceholder();

        // Message: Starting download.
        lprintfln("Starting download");

        // The image shall be downloaded from the following url.
        mImageDownloader->beginDownloading(
            "http://shop.abc.net.au/multimediaitems/images/product_images/4/482912.png",
            mImageResource);
    }

    /*
     * The destructor.
     */
    virtual ~MyScreen()
    {
        delete mImageDownloader;
        maDestroyObject(mImageResource);
    }

    /*
     * The function is fired in case of download cancellation.
     */
    void downloadCancelled(Downloader* downloader)
    {
        lprintfln("Cancelled");
    }

    /*
     * Method displays error code in case of error in downloading.
     */
    void error(Downloader* downloader, int code)
    {
        lprintfln("Error: %d", code);
    }

    /*
     * On successful download completion, the image file is shown on screen.
     */
    void finishedDownloading(Downloader* downloader, MAHandle data)
    {
        lprintfln("Completed download");

        // Create a new image on screen with this picture.
        Image* myImage = new Image(0, 0, 240, 320, NULL, false, false, mImageResource);
        this->setMain(myImage);
        this->show();
    }

    /*
     * Notifies download progress.
     */
    void notifyProgress(
        Downloader* downloader,
        int downloadedBytes,
        int totalBytes)
    {
        lprintfln("Downloaded %d of %d bytes", downloadedBytes, totalBytes);
    }

private:
    ImageDownloader* mImageDownloader;
    MAHandle mImageResource;
};

/*
 * Moblet for the image download.
 */
class MAUIMoblet : public Moblet
{
public:
    MAUIMoblet()
    {
        // Create the screen.
        mScreen = new MyScreen();
        mScreen->show();
    }

    /*
     * Key press events are handled here.
     */
    void keyPressEvent(int keyCode)
    {
        if(keyCode == MAK_0 || keyCode == MAK_BACK)
        {
            maExit(0);
        }
    }

    void keyReleaseEvent(int keyCode)
    {
        // todo: handle key releases
    }

    /*
     * The destructor.
     */
    virtual ~MAUIMoblet()
    {
        delete mScreen;
    }

private:
    MyScreen* mScreen;
};

/**
 * Main function that starts the program.
 */
extern "C" int MAMain()
{
    Moblet::run(new MAUIMoblet());
    return 0;
}

In this example, the DownloadListener is also a MAUI Screen class.  When the finishedDownloading method is called, the MAHandle 'data' contains a handle to the downloaded image.  You can then display this as any other MAUI image, or in a game or a C application, you can use the function maDrawImage().

If you tried this with a Downloader object instead of an ImageDownloader, you’ll get an ‘Invalid Resource Type’ error message when you tried to create the image.  Instead, you’d need to call:

maCreateImageFromData(h, source, position, imageLength);

to covert the resource type for you.

MoSync SDK 3.3
Copyright © 2013 MoSync AB
www.mosync.com