Setting tab icon image from url - android

I have an application that has a set of tabs with images set as the TabIndecator. I want to take an image from a URL and set the TabIndecator image as the URL that is specified for that particular tab. Is there a way to do so? Can I take a ImageView and set it as the TabIndecator?

I want to take an image from a URL and set the TabIndecator image as the URL that is specified for that particular tab. Is there a way to do so?
Not directly, you have to download the image to the device as a Bitmap, wrap it in a BitmapDrawable, and set it with TabSpect.setIndicator()
Can I take a ImageView and set it as the TabIndecator?
Sure, TabSpec.setIndicator() can take a View as an argument if you so choose.

This method will allow you to get a local Bitmap from image's URL. My comments are in Spanish but I hope this example will be useful anyway. Make sure to run it in a AsyncTask or similar (not on UI Thread):
private static final int IO_BUFFER_SIZE = 8 * 1024;
private static final int MINIMO_TAM = 10;
public static final int MAXIMO_TAM = 640;
public static Bitmap loadRemoteImage(CharSequence urlImagen) {
if (null == urlImagen) {
return null;
}
Bitmap bm = null;
InputStream is = null;
BufferedInputStream bis = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.addRequestInterceptor(new GzipHttpRequestInterceptor());
httpclient.addResponseInterceptor(new GzipHttpResponseInterceptor());
try {
String urlSinEspacios = urlImagen.toString().replace(" ", "+");
// Hacer la llamada
HttpGet httpget = new HttpGet(urlSinEspacios);
HttpEntity entity = httpclient.execute(httpget).getEntity();
is = entity.getContent();
bis = new BufferedInputStream(is, IO_BUFFER_SIZE);
//Obtener solo el tamaƱo
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(bis, null, o);
try {
bis.close();
is.close();
} catch (Exception e) {
}
//Calcular mejor escala
int scale = 1;
if (o.outHeight > MAXIMO_TAM || o.outWidth > MAXIMO_TAM) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(MAXIMO_TAM / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Descargar el real
entity = httpclient.execute(httpget).getEntity();
is = entity.getContent();
bis = new BufferedInputStream(is, IO_BUFFER_SIZE);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16 * 1024];
options.inSampleSize = scale;
bm = BitmapFactory.decodeStream(bis, null, options);
// Finalizado
httpclient.getConnectionManager().shutdown();
} catch (Exception e) {
bm = null;
} finally {
try {
bis.close();
is.close();
// Finalizado
httpclient.getConnectionManager().shutdown();
} catch (Exception e) {
}
}
return bm;
}
Then, you can use a BitmapDrawable to wrap this Bitmap and use with:
tabHost.newTabSpec("TODO").setIndicator("TODO", TODO).setContent(TODO);

Related

BitmapFactory.decodeStream returns null, when downloading a image form web

I'm trying to download a image from a URL, using the Google Example Page. I've read when I use a InputStream in the BitmapFactory.decodeStream method, I can't use twice. I'm trying to do that, but it doesn't work 'cause it returns null in the decoded image, and I don't know what I can do.
This is my code:
This part is in a doInBackground method in a AsyncTask class
Bitmap bitmapImage;
URL imageUrl = null;
try {
imageUrl = new URL(url[0]);
HttpGet httpRequest = null;
httpRequest = new HttpGet(imageUrl.toURI());
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
bitmapImage = CommonMethods.decodeSampledBitmapFromResource(instream, thumb_width, thumb_width);
instream.close();
return bitmapImage;
} catch (URISyntaxException e) {
e.printStackTrace();
return null;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
public static Bitmap decodeSampledBitmapFromResource(InputStream instream,
int reqWidth, int reqHeight) throws IOException {
//Copy instream for decode twice
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(instream,out);
ByteArrayInputStream instream2 = new ByteArrayInputStream(out.toByteArray());
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(instream, null, options);
instream2.close();
options.inJustDecodeBounds = false;
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
return BitmapFactory.decodeStream(instream, null, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
//Copy instream method
public static void copy(InputStream input, OutputStream output) throws IOException{
byte[] buffer = new byte[Constants.IO_BUFFER_SIZE];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
}
BitmapFactory.decodeStream returns null because the inputstream is used twice, I've not tried your code, but it seams OK, or maybe I'm wrong.
Anyway, I've a better solution. Just use BufferedInputStream to wrap the inputStream, and before your second read, call "reset" first. Note ordinary inputStreams donnot support "reset", you may call it but nothing will happen.
My code:
public static Bitmap decodeSampledBitmapFromStream(InputStream inputStream,
int reqWidth, int reqHeight)
throws IOException {
if (!widthHeightCheck(reqWidth, reqHeight))
return BitmapFactory.decodeStream(inputStream);
// First decode with inJustDecodeBounds=true to check dimensions
if (!(inputStream instanceof BufferedInputStream)) {
inputStream = new BufferedInputStream(inputStream);
}
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Rect rect = new Rect(-1, -1, -1, -1);
BitmapFactory.decodeStream(inputStream, rect, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
inputStream.reset();
return BitmapFactory.decodeStream(inputStream, rect, options);
}
I think you can achieve this by wrapping the stream you get from the httpEntity in a custom WrappedStream. This WrappedStream will feed a second input stream while reading the original stream. (this is done with PipedStream)
After getting the image size with this code :
options.inJustDecodeBounds = true;
WrappedStream wrappedStream = new WrappedStream(instream);
BitmapFactory.decodeStream(wrappedStream, null, options);
You can call
InputStream reReadStream = wrappedStream.getReReadStream();
options.inJustDecodeBounds = false;
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
return BitmapFactory.decodeStream(reReadStream, null, options);
And finally, here is the implementation of WrappedStream (it simply delegates all calls to the wrapped inputStream, and writes all bytes that are read (or skipped) in a pipedOutputStream)
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/** Simple class wrapping an InputStream and feeding a secondary InputStream
* to re-read the data that was originally available in the inputStream.
**/
public class WrappedStream extends InputStream {
private InputStream urlStream;
private PipedOutputStream pipedStream;
public WrappedStream(InputStream urlStream) {
this.urlStream = urlStream;
this.pipedStream = new PipedOutputStream();
}
/**
* return a fresh InputStream to re-read the data
*/
public InputStream getReReadStream() throws IOException {
return new PipedInputStream(pipedStream);
}
#Override
public int available() throws IOException {
return urlStream.available();
}
#Override
public void close() throws IOException {
urlStream.close();
}
#Override
public void mark(int readlimit) {
urlStream.mark(readlimit);
}
#Override
public boolean markSupported() {
return urlStream.markSupported();
}
#Override
public int read() throws IOException {
int b = urlStream.read();
pipedStream.write(b);
return b;
}
#Override
public int read(byte[] buffer) throws IOException {
int l = urlStream.read(buffer);
pipedStream.write(buffer);
return l;
}
#Override
public int read(byte[] buffer, int offset, int length) throws IOException {
int l = urlStream.read(buffer, offset, length);
pipedStream.write(buffer, offset, length);
return l;
}
#Override
public void reset() throws IOException {
urlStream.reset();
}
#Override
//bytes skipped must available on the re-read stream so we read and write them.
public long skip(long byteCount) throws IOException {
long bytesToSkip = byteCount;
long skippedBytes = 0;
//ugly trick required to not loosing bytes if we ever skip more than Integer.MAX_VALUE bytes
while(bytesToSkip>Integer.MAX_VALUE){
_skip(Integer.MAX_VALUE);
bytesToSkip -=Integer.MAX_VALUE;
skippedBytes +=Integer.MAX_VALUE;
}
byte[] b = new byte[(int)bytesToSkip];
skippedBytes += read(b);
return skippedBytes;
}
private int _skip(int byteCount) throws IOException {
byte[] b = new byte[(int)byteCount];
return read(b);
}
}
Please note that I didn't test this code. This is just to give you some ideas on how to solve your problem.
Another point: even if this code never create a huge bitmap, the whole stream will be kept in memory until the scaled Bitmap is build.
Found the code which will work for you
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
//options.inSampleSize = 2;
final Bitmap bitmap = BitmapFactory
.decodeStream(inputStream, null, options);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
Please replace the proper variable and if you wanted to scale the image you can scale it after getting the bitmap.
here is the method to download bitmap from server with less code you can fulfill your requirement
Bitmap downloadBitmap(String url)
{
Bitmap image = null;
InputStream in = null;
try
{
in = new java.net.URL(url).openStream();
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
image = BitmapFactory.decodeStream(new FlushedInputStream(in),null,opts);
in.close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return image;
}
in the above code we use
opts.inSampleSize = 2;
it means the bitmap will be reduced to half size of its original size to avoid memory exception we have to do this if we are loading lot of images
some other class used in it
static class FlushedInputStream extends FilterInputStream
{
public FlushedInputStream( InputStream inputStream )
{
super(inputStream);
}
#Override
public long skip(long n) throws IOException
{
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n)
{
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L)
{
int byte1 = read();
if (byte1 < 0)
{
break; // we reached EOF
}
else
{
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
Please Use below code for download and display image into imageview.
public class image extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bitmap bitmap = DownloadImage("http://www.gophoto.it/view.php?i=http://1.bp.blogspot.com/-2LTvCCufBKc/T3L3KgcTj2I/AAAAAAAABbQ/Ki60e1LU9sE/s1600/Sachin%2BTendulkar.png");
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(bitmap);
}
private InputStream OpenHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
} catch (Exception ex) {
throw new IOException("Error connecting");
}
return in;
}
private Bitmap DownloadImage(String URL) {
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return bitmap;
}
}

How can I resize the image that was retrieved via URL and save it?

I am getting an image via URL from the Internet and trying to resize (to a smaller size) before saving it. I managed to save it, but I'm unable to resize it. How could I do that? Here is the code:
URL url = new URL(LogoURL);
InputStream input = url.openStream();
try {
OutputStream output = new FileOutputStream("data/data/com.android.mylogo/logo.jpg");
try {
//byte[] buffer = new byte[aReasonableSize];
int bytesRead = 0;
System.out.println("Buffer Length is \t:-" + buffer.length);
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
System.out.println("inside while");
output.write(buffer, 0, bytesRead);
}
} finally {
output.close();
System.out.println("saved image");
}
} finally {
input.close();
}
If you want to downscale the image to particular dimensions, you can use the following code:
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(LogoURL);
try {
HttpResponse response = client.execute(request);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(LOG_TAG, "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream is = null;
BufferedInputStream bis = null;
try {
is = url.openStream();
bis = new BufferedInputStream(is);
int sampleSize = 1;
bis.mark(Integer.MAX_VALUE);
Options bounds = new Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeStream(bis, null, bounds);
if (bounds.outWidth != -1) {
int width = bounds.outWidth;
int height = bounds.outHeight;
boolean withinBounds = width <= YOUR_DESIRED_WIDTH && height <= YOUR_DESIRED_HEIGHT;
int newWidth = width;
int newHeight = height;
while (!withinBounds) {
newWidth /= 2;
newHeight /= 2;
sampleSize *= 2;
withinBounds = newWidth <= YOUR_DESIRED_WIDTH && newHeight <= YOUR_DESIRED_HEIGHT;
}
} else {
Log.w(LOG_TAG, "Can't open bitmap at " + url);
return null;
}
try {
bis.reset();
} catch (IOException e) {
if(is != null){
is.close();
}
if(bis != null){
bis.close();
}
if(!entity.isRepeatable()){
entity.consumeContent();
response = client.execute(request);
entity = response.getEntity();
}
is = entity.getContent();
bis = new BufferedInputStream(is);
}
Options opts = new Options();
opts.inSampleSize = sampleSize;
Bitmap bm = BitmapFactory.decodeStream(bis, null, opts);
return bm;
} finally {
if (is != null) {
is.close();
}
if (bis != null) {
bis.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
request.abort();
Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
request.abort();
Log.w(LOG_TAG, "Incorrect URL: " + url);
} catch (Exception e) {
request.abort();
Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
}
When you open the image with Options bounds = new Options(); bounds.inJustDecodeBounds = true;, then the image data won't be downloaded, only the size of the image. I use this size to calculate the new scale ratio to get the desired width and height.
With the option Options opts = new Options(); opts.inSampleSize = sampleSize; the BitmapFactory will download an already resized image. You save memory, and bandwidth this way.
Note, that the sampleSize values should be powers of 2. It works with different numbers as well, but this is much more efficient.
JPGs are compressed anyway, so there's no need to try to compress them any further.
In general, to compress something, have a look at the classes of java.util.zip package.

image from url to drawable or bitmap :best and fastest way

im tried to show images from url in my app. But ways which im using is very long .
this code i founded on stackoverflow
public Bitmap getImage(String url,String src_name) throws java.net.MalformedURLException, java.io.IOException {
Bitmap bitmap;
HttpURLConnection connection = (HttpURLConnection)new URL(url) .openConnection();
connection.setRequestProperty("User-agent","Mozilla/4.0");
connection.connect();
InputStream input= connection.getInputStream();
bitmap = BitmapFactory.decodeStream(input);
return bitmap;
}
10 images loaded in 10-12 second. if used this code.
and
///==========================================================================================================================================
public Drawable getImage(String url, String src_name) throws java.net.MalformedURLException, java.io.IOException
{
Drawable abc =Drawable.createFromStream(((java.io.InputStream)new java.net.URL(url).getContent()), src_name);
return abc;
}
if using this code - images loaded in 9-11 seconds.
Images not big . max width or height is 400-450.
ofcourse i tell this function in cycle like this : for (int i =0;i<10;i++){image[i]=getImage(url);}
Can any tell how to best and faste show image in my app ?
regards, Peter.
You cannot do away with the time required for downloading and decoding images. The number '10' is just a function on the quality of the image and you can only try to optimize on this number.
If the server is managed by you, you might want to spend some time optimizing on the size of the downloadable images given your UI requirements. Also try lazy-loading (I hope you are not performing these operations on the UI thread). Many solutions for lazy-downloading and lazy-decoding have been discussed many times: http://www.google.com.sg/search?q=android+images+lazy+load&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
Sidenote: The usage of HttpURLConnection is discouraged. Use the HttpClient. This might also affect performance. Take a look at http://lukencode.com/2010/04/27/calling-web-services-in-android-using-httpclient/
public static Bitmap getBitmapFromUrl(String url) {
Bitmap bitmap = null;
HttpGet httpRequest = null;
httpRequest = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = null;
try {
response = (HttpResponse) httpclient.execute(httpRequest);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (response != null) {
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = null;
try {
bufHttpEntity = new BufferedHttpEntity(entity);
} catch (IOException e) {
e.printStackTrace();
}
InputStream instream = null;
try {
instream = bufHttpEntity.getContent();
} catch (IOException e) {
e.printStackTrace();
}
bitmap = BitmapFactory.decodeStream(instream);
}
return bitmap;
}
public static Bitmap decodeFile(String filePath) {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2);
return bitmap;
}

Android : Big error while downloading images

I have tried three ways of downloading images. All suggest by members of Stackoverflow .
All the three methods fail to download all the images from the server. Few are downloaded and few are not.
I noticed a thing that each of the method fail to download image from particular position.
That is method 3 always fails to download the first three images. I changed the images but even then , the first three images are not downloaded.
Method 1:
public Bitmap downloadFromUrl( String imageurl )
{
Bitmap bm=null;
String imageUrl = imageurl;
try {
URL url = new URL(imageUrl); //you can write here any link
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
bm= BitmapFactory.decodeByteArray(baf.toByteArray(), 0, baf.toByteArray().length);
} catch (IOException e) {
Log.d("ImageManager", "Error: " + e);
}
return bm;
}
Here the error i get for missed images is :SKIimagedecoder , the factory returned null.
Method: 2
public static Bitmap loadBitmap(String url)
{
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(new URL(url).openStream(), 4*1024);
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, 4 * 1024);
int byte_;
while ((byte_ = in.read()) != -1)
out.write(byte_);
out.flush();
final byte[] data = dataStream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
//options.inSampleSize = 1;
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
} catch (IOException e) {
System.out.println(e);
Log.e("","Could not load Bitmap from: " + url);
} finally {
try{
in.close();
out.close();
}catch( IOException e )
{
System.out.println(e);
}
}
return bitmap;
}
The error i get here is same as above.
Method 3:
private Bitmap downloadFile(String fileUrl){
URL bitmapUrl =null;
Bitmap bmImg = null;
try {
bitmapUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpGet httpRequest = null;
try {
httpRequest = new HttpGet(bitmapUrl.toURI());
} catch (URISyntaxException e) {
e.printStackTrace();
}
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient
.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
bmImg = BitmapFactory.decodeStream(instream);
} catch (Exception e) {
System.out.println(e);
}
return bmImg;
}
The error i get here is : org.apache.http.NoHttpResponseException: The target server failed to respond.
please help. It is the only thing stopping me from completing the project.
Take a look at this.. Clearly explained about image download from the Server..Image from Server....
I'm assuming you are downloading the images to display rather than just save on the device. If this is the case, I recommend looking into using Droid-Fu, more specifically WebImageView. You can just pass the URL to the WebImageView and it will load the image as it can, which will avoid having an image fail to load because of the connection timing out, which I'm guessing is the problem you are having.
In XML:
<com.github.droidfu.widgets.WebImageView
android:id="#+id/image"
android:layout_width="70dip"
android:layout_height="70dip"
droidfu:autoLoad="true"
droidfu:progressDrawable="..."
/>
In Code:
WebImageView image = (WebImageView) convertView.findViewById(R.id.image);
image.setImageUrl(image_url);
image.loadImage();
It's possible that your creation of bitmaps takes time and therefore the connection times out. You could possibly get references to all the inputstreams and then download and create. This is a rough-cut answer, but if the reasoning is right, you can improve on it:
public Bitmap[] downloadFromUrl(String[] imageUrls)
{
Bitmap[] bm = new Bitmap[imageUrls.length];
BufferedInputStream[] bis = new BufferedInputStream[imageUrls.length];
for (int i = 0; i < imageUrls.length; i++)
{
try
{
URL url = new URL(imageUrls[i]); // you can write here any link
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
bis[i] = new BufferedInputStream(is);
}
catch (IOException e)
{
e.printStackTrace();
}
}
for (int i = 0; i < bis.length; i++)
{
try
{
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis[i].read()) != -1)
{
baf.append((byte) current);
}
bm[i] = BitmapFactory.decodeByteArray(baf.toByteArray(), 0, baf.toByteArray().length);
}
catch (IOException e)
{
e.printStackTrace();
}
}
return bm;
}

How to handle out of memory error?

I am using following code to display bitmap in my ImageView.
When I try to load image of size for example bigger than 1.5MB it give me error.
Any one suggest me solution?
try {
URL aURL = new URL(myRemoteImages[val]);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = null;
try
{
is= conn.getInputStream();
}catch(IOException e)
{
return 0;
}
int a= conn.getConnectTimeout();
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bm;
try
{
bm = BitmapFactory.decodeStream(bis);
}catch(Exception ex)
{
bis.close();
is.close();
return 0;
}
bis.close();
is.close();
img.setImageBitmap(bm);
} catch (IOException e) {
return 0;
}
return 1;
Log cat:
06-14 12:03:11.701: ERROR/AndroidRuntime(443): Uncaught handler: thread main exiting due to uncaught exception
06-14 12:03:11.861: ERROR/AndroidRuntime(443): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
06-14 12:03:11.861: ERROR/AndroidRuntime(443): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
You should decode with inSampleSize option to reduce memory consumption. Strange out of memory issue while loading an image to a Bitmap object
Another option inJustDecodeBounds can help you to find correct inSampleSize value http://groups.google.com/group/android-developers/browse_thread/thread/bd858a63563a6d4a
In general I think this blog covers the best practices on how to watch memory allocation/ how to use Weak/Soft References to avoid overflows.
Hope this helps.
try {
Bitmap bitmap=null;
byte[] profileImageInBytes;
String url="http://photo.net/learn/collage/complete-full-size.jpg";
HttpGet httpRequest = null;
httpRequest = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
System.gc();
Runtime.getRuntime().gc();
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
bmpFactoryOptions.inTempStorage = new byte[32 * 1024];
bmpFactoryOptions.inSampleSize = 4;
bmpFactoryOptions.outWidth = 640;
bmpFactoryOptions.outHeight = 480;
bmpFactoryOptions.inDither=false;
bmpFactoryOptions.inInputShareable=true;
bitmap = BitmapFactory.decodeStream(instream, new Rect(), bmpFactoryOptions);
System.out.println("hi " +bitmap);
Bitmap map = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
System.out.println("23");
System.out.println("hihi hi " +map);
BitmapDrawable bmd = new BitmapDrawable(map);
System.out.println("24");
System.out.println("hihi hi " +bmd);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
System.out.println(stream);
map.compress(Bitmap.CompressFormat.JPEG, 100, stream);
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) 400);
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) 400);
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
Bundle params=new Bundle();
params.putString("method", "photos.upload");
profileImageInBytes = stream.toByteArray();
System.out.println(profileImageInBytes);
System.out.println(" profile image bytes ");
System.out.println("Bytes : " + profileImageInBytes);
params.putByteArray("picture", profileImageInBytes);
System.out.println("My Picture : " + params);
mAsyncRunner.request(null, params, "POST",
new SampleUploadListener(), null);
System.out.println("Uploading");
}
catch (IOException e) {
e.printStackTrace();
}

Categories

Resources