Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load Image from Image URL taking so much time to display

I used the code from the following link: Signare's Blog. I have 10 image URLs and would like to retrieve and show them on my screen. When I use the code from the above link, it's taking more than 10 minutes to load all of the images. How do I speed up this loading?

URLBitmapField post_img= new URLBitmapField(image_url);
add(post_img);

where the class URLBitmapField is defined as:

import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;

public class URLBitmapField extends BitmapField implements URLDataCallback {
    EncodedImage result = null;
    public static EncodedImage _encoded_img = null;
    int _imgWidth = 52;
    int _imgHeight = 62;
    int _imgMargin = 10;

    public URLBitmapField(String url) {
        try {
            http_image_data_extrator.getWebData(url, this);
        }
        catch (Exception e) {}
    }

    public Bitmap getBitmap() {
        if (_encoded_img == null) return null;
        return _encoded_img.getBitmap();
    }

    public void callback(final String data) {
        if (data.startsWith("Exception")) return;
        try {
            byte[] dataArray = data.getBytes();
            _encoded_img = EncodedImage.createEncodedImage(dataArray, 0, dataArray.length); // with scale
            _encoded_img = sizeImage(_encoded_img, _imgWidth, _imgHeight);
            setImage(_encoded_img);
            UiApplication.getUiApplication().getActiveScreen().invalidate();
        }
        catch (final Exception e){}
    }

    public EncodedImage sizeImage(EncodedImage image, int width, int height) {
        int currentWidthFixed32 = Fixed32.toFP(image.getWidth());
        int currentHeightFixed32 = Fixed32.toFP(image.getHeight());
        int requiredWidthFixed32 = Fixed32.toFP(width);
        int requiredHeightFixed32 = Fixed32.toFP(height);
        int scaleXFixed32 = Fixed32.div(currentWidthFixed32,requiredWidthFixed32);
        int scaleYFixed32 = Fixed32.div(currentHeightFixed32,requiredHeightFixed32);
        result = image.scaleImage32(scaleXFixed32, scaleYFixed32);
        return result;
    }
}

public interface URLDataCallback {
    public void callback(String data);
}

and the class http_image_data_extrator is defined as:

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.WLANInfo;
import net.rim.device.api.ui.UiApplication;

public class http_image_data_extrator {
    static String url_="";
    static StringBuffer rawResponse=null;

    public static void getWebData(String url, final URLDataCallback callback) throws IOException {
        HttpConnection connection = null;
        InputStream inputStream = null;
        try {
            if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)&& RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
                url += ";interface=wifi";
            }
            connection = (HttpConnection) Connector.open(url, Connector.READ, true);
            String location=connection.getHeaderField("location");
            if(location!=null){
                if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)&& RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
                    location += ";interface=wifi";
                }
                connection = (HttpConnection) Connector.open(location, Connector.READ, true);
            }else{
                connection = (HttpConnection) Connector.open(url, Connector.READ, true);
            }

            inputStream = connection.openInputStream();
            byte[] responseData = new byte[10000];
            int length = 0;
            rawResponse = new StringBuffer();
            while (-1 != (length = inputStream.read(responseData))) {
                rawResponse.append(new String(responseData, 0, length));
            }
            int responseCode = connection.getResponseCode();
            if (responseCode != HttpConnection.HTTP_OK){
                throw new IOException("HTTP response code: "+ responseCode);
            }

            final String  result = rawResponse.toString();
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run(){
                    callback.callback(result);
                }
            });
        }
        catch (final Exception ex) {
            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    callback.callback("Exception (" + ex.getClass() + "): " + ex.getMessage());
                }
            });
        }
    }
}  
like image 447
Rince Thomas Avatar asked Nov 06 '12 05:11

Rince Thomas


1 Answers

Resize on the server

Resizing the images on the server is the best answer. Because downloading big images and scaling them down requires a lot of everything (network, memory, cpu) on the device.

Resize via a proxy

If the image server is not under your control, you could still use your own server as a resizing proxy (send the image url and desired size to your server, it gets the image, resizes, and returns the resized image). Maybe there is a service that does this already.

Cheaper decode option

Some decode options may make decoding (and resizing) cheaper. DECODE_NO_DITHER, DECODE_READONLY, and DECODE_NATIVE all seem worth trying.
http://www.blackberry.com/developers/docs/4.2api/net/rim/device/api/system/EncodedImage.html#DECODE_NO_DITHER

Serial instead of parallel

You mentioned you are loading 10 images. If 10 images takes more than 10x the time 1 image takes, then the system might be "thrashing". Like it might initiate all 10 requests, then wind up working on 10 fullscale images in memory at the same time in callbacks. Could try showing the first image before starting to download the next, which also gives the user something to look at sooner. Similarly, calling invalidate 10 times in parallel (in the callback) might cause a hiccup.

like image 166
leorleor Avatar answered Sep 24 '22 05:09

leorleor