Load Image from Image URL taking so much time to display
Asked Answered
C

1

12

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());
                }
            });
        }
    }
}  
Cerebritis answered 6/11, 2012 at 5:19 Comment(15)
If you want to Display BitMapImages on BlackBerry Screen , you can go through this Click Here there you will find one example on BlackBerry RssFeed ReaderPromotion
use database in ur app insert those images in ur DBFluter
that is not possible..@RajKamalCerebritis
that is not my requirement @RajKamalCerebritis
M maintaing gallery by using DBFluter
the above code is also taking so much time.Cerebritis
i tried. But its taking too much time...Cerebritis
How big are the images? Could you also check that you don't recreate BitmapFields on some event?Opulent
@EugenMartynov its normal 1024x768 images. check the above code.Cerebritis
Could you explain why do you need such big images? Because there is no any java bb with such resolution. So the net is slow and images are big, as well next resizing takes some time, as well String.getBytes() will generate new array - more memory and time. As well default download type without wifi is DirectTCP which could be limitedOpulent
@EugenMartynov the image is uploading from the pc(web). so i can't do anything.Cerebritis
You resize image 1024x768 to 52x68. First of all why it has different aspect ratio? I think you could try to load image partly (like web browsers do for first preview) so download not all pixels but every 5th or 10th. But this requires that image on server is ready for this kind of download.Opulent
@EugenMartynov The image is taken from the desktop. so i cant show this big image in the mobile. so i resize it. its users profile images. so i want to show the small image and name in a single line using a list. if there are 100 users, it will take more than an hour to load........Cerebritis
@BlackPearl, If you want to download large file, it will take long time. You need to do something on server side before downloading.Koonce
You create a new String just to append its contents to the buffer, then it is discarded. One of the optimization approaches could be to read all data into ByteArrayOutputStream instead and convert into image in one go. This would help if some time is lost in garbage collection.Randolphrandom
P
1

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.

Pood answered 24/2, 2013 at 20:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.