I try to load a remote image from a server and thanks to a lot of code examples on stackoverflow I have a solution which works in 2 out of 3 images. I don't really know what the problem is with the third picture and sometimes when letting the code run in the debugger the picture is loading. Also if I load the problem picture first the other two pictures are sometimes not loaded.
Here is the code:
public static Drawable getPictureFromURL(Context ctx, String url, final int REQUIRED_SIZE) throws NullPointerException {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
int scale = 1;
if (o.outWidth > REQUIRED_SIZE) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(REQUIRED_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
Log.i(Prototype.TAG, "scale: "+scale);
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bmp;
try {
bmp = BitmapFactory.decodeStream((InputStream) Tools.fetch(url), null, o2);
if(bmp!=null)
return new BitmapDrawable(ctx.getResources(), bmp);
else
return null;
} catch (Exception e) {
Log.e(Prototype.TAG, "Exception while decoding stream", e);
return null;
}
}
During debugging I found out that o.outWidth is -1 which indicates an error, but no Exception is thrown, so I can't really tell what went wrong. The InputStream always returned a valid value, and I know that the picture exists on the server.
Best wishes,
Daniel
I found the answer here and updated the fetch method to:
private static InputStream fetch(String address) throws MalformedURLException,IOException {
HttpGet httpRequest = new HttpGet(URI.create(address) );
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
return instream;
}
Related
I want to load Bitmap from Url in a background thread. My method looks like below.
public Bitmap decodeSampledBitmapFromURL(String url,int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream is=null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Rect rect = new Rect(-1, -1, -1, -1);
Bitmap bmp1 = BitmapFactory.decodeStream(is,rect, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bmp2 = BitmapFactory.decodeStream(is,rect, options);
return bmp2;
}
I always get bmp1 and bmp2 as null. why?
maybe check if input stream is null, to se whether bad bitmap code or getting input stream code.
maybe Rect should have proper dimensions?
you are decoding the stream with option to decode bounds so obviously the bitmap out put will be null, and then you are trying to decode bitmap from the same stream, which was already used in the first decoding. You can try reading the stream to byte array buffer and then wrap bytearrayInputstreams, remember to create new streams for each decoding
Here is my code and i get an outofMemory exception while downloading multiple images. I hv gone through a duplicate question but did not find a suitable reply.
try {
HttpGet httpRequest = new HttpGet("http://staging.xyz.com/db/demo_img/abc.png");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(entity);
InputStream is = bufferedHttpEntity.getContent();
//Drawable d = Drawable.createFromStream(is, "");
//or bitmap
//photos = BitmapFactory.decodeStream(is);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is,null,o);
//The new size we want to scale to
final int REQUIRED_SIZE=70;
//Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
scale*=2;
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
Bitmap photos= BitmapFactory.decodeStream(is, null, o2);
} catch (MalformedURLException e) {
System.out.println("photo error1111");
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
System.out.println("photo error1111");
// TODO Auto-generated catch block
e.printStackTrace();
}
I noticed that you do not recycle the bitmap. Could that the the source of your problems?
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
photos.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
just add this it will save ur memory
or simply try this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2; CameraAndFolderActivity.myBitmap = BitmapFactory.decodeFile(info.aImagePath, options);
use the garbage collector..
System.gc();
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);
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;
}
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();
}