Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting image url to bitmap quickly

I need to display the list of images from api in the list page. For that i used two approaches.

First Approach:
By converting the url to byte array and then converting it into bitmap.Please find the below code..

URL imageUrl = new URL(url);
URLConnection ucon = imageUrl.openConnection();

InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);

ByteArrayBuffer baf = new ByteArrayBuffer(500);
int current = 0;
while ((current = bis.read()) != -1) {
     /* This approach slowdown the process*/
     baf.append((byte) current);
}

byte[] img_ary= baf.toByteArray();

Converting byte array to bitmap:

ByteArrayInputStream imageStream = new ByteArrayInputStream(
                    imgUrl);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);

Second Approach:
Image scaling based on height and width

private static final String TAG_iamge = "Image";
private static final int IO_BUFFER_SIZE = 4 * 1024;

public static Bitmap loadBitmap(String url) {
    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;

    try {
        in = new BufferedInputStream(new URL(url).openStream(),
                IO_BUFFER_SIZE);

        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
        copy(in, out);
        out.flush();

        final byte[] data = dataStream.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();

        options.inJustDecodeBounds = true;
        options.inDither = false;
        options.inPurgeable = true;
        options.inInputShareable = true;

        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
                options);

        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        int reqHeight = 500;
        int reqWidth = 500;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2
            // and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        int scale = inSampleSize;

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        o2.inDither = false;
        o2.inPurgeable = true;
        o2.inInputShareable = true;
        return BitmapFactory.decodeByteArray(data, 0, data.length, o2);
    } catch (Exception e) {
        Log.e(TAG_iamge, "Could not load Bitmap from: " + url);
    } finally {
        closeStream(in);
        closeStream(out);
    }

    return bitmap;
}

private static void copy(InputStream in, OutputStream out)
        throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    while ((read = in.read(b)) != -1) {
        out.write(b, 0, read);
    }
}

private static void closeStream(Closeable stream) {
    if (stream != null) {
        try {
            stream.close();
        } catch (IOException e) {
            android.util.Log.e("", "Could not close stream", e);
        }
    }
}

Both approaches making the APP very slow. So here is my questions..

  1. How can i quickly convert the url into bitmap without making the app slow?

  2. How the other apps(like flipcart) displaying the 1000>s of images, without any slow or hang?

    Please guide to get the answer.

like image 643
Booshan Avatar asked May 15 '15 09:05

Booshan


People also ask

How to create bitmap from url in Android Studio?

This example demonstrates how do I get a bitmap from Url in android app. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.

Can object be converted into bitmap?

Converting a vector graphic or object to a bitmap lets you apply special effects to the object with CorelDRAW. The process of converting a vector graphic to a bitmap is also known as “rasterizing.” When you convert the vector graphic, you can select the color mode of the bitmap.

What is Uri and bitmap?

Bitmap is a ready image ( set of bytes with color data ) and URI is a path to something. URI can be /emulated/home/... , can be http://google.com and so on.


1 Answers

There is a library named Picasso. which can efficiently load images from url. it can also load image from the File. all you wanted to do , write a line of code.

example

Picasso.with(context) //Context
    .load("http://i.imgur.com/DvpvklR.png") //URL/FILE
    .into(imageView)//an ImageView Object to show the loaded image; 

It can also cache your image, so the loaded image could be able to load faster on the next time without wasting the data.

There are many more options available in Picasso. Here is the documentation

If you need rounded cornered bitmap

Picasso.with(mContext)
    .load("your-image-url-or-file-or-drawable")
    .transform(new RoundedTransformation(200, 0))
    .fit()
    .into(imageView);

RoundedTransformation.java

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;

// enables hardware accelerated rounded corners
// original idea here : http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
public class RoundedTransformation implements com.squareup.picasso.Transformation {
    private final int radius;
    private final int margin;  // dp

    // radius is corner radii in dp
    // margin is the board in dp
    public RoundedTransformation(final int radius, final int margin) {
        this.radius = radius;
        this.margin = margin;
    }

    @Override
    public Bitmap transform(final Bitmap source) {
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));

        Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        canvas.drawRoundRect(new RectF(margin, margin, source.getWidth() - margin, source.getHeight() - margin), radius, radius, paint);

        if (source != output) {
            source.recycle();
        }

        return output;
    }

    @Override
    public String key() {
        return "rounded";
    }
}
like image 115
theapache64 Avatar answered Oct 16 '22 13:10

theapache64