问题
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..
- How can i quickly convert the url into bitmap without making the app slow?
How the other apps(like flipcart) displaying the 1000>s of images, without any slow or hang?
Please guide to get the answer.
回答1:
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";
}
}
回答2:
There are open-source libraries which focus on loading image into an ImageView
. Take for example of universal-image-loader, it is very easy to use, like:
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);
or:
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
or:
// Load image, decode it to Bitmap and return Bitmap synchronously
Bitmap bmp = imageLoader.loadImageSync(imageUri);
Take example of Volley, you can use it like this:
public void displayImg(View view){
ImageView imageView = (ImageView)this.findViewById(R.id.image_view);
RequestQueue mQueue = Volley.newRequestQueue(getApplicationContext());
ImageLoader imageLoader = new ImageLoader(mQueue, new BitmapCache());
ImageListener listener = ImageLoader.getImageListener(imageView,R.drawable.default_image, R.drawable.default_image);
imageLoader.get("http://developer.android.com/images/home/aw_dac.png", listener);
//指定图片允许的最大宽度和高度
//imageLoader.get("http://developer.android.com/images/home/aw_dac.png",listener, 200, 200);
}
These libraries are used broadly, and more importantly, they are open-sourced. No need to implement functions like this repeatedly.
回答3:
Try this
Hope this should help you.来源:https://stackoverflow.com/questions/30256060/converting-image-url-to-bitmap-quickly