I want to copy the content of an input-stream which is actually a bitmap to a file-output-stream. After that I want to pass the content of the file-output-stream to BitmapFactory.decodeStream. The result is that I am getting damaged images! my code for these things is the below.
private void copyInStreamToFile(InputStream is) {
byte buf[] = new byte[1024];
int len;
FileOutputStream fos;
try {
fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
while ((len = is.read(buf)) > 0)
fos.write(buf, 0, len);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static FileInputStream getStream() throws FileNotFoundException {
return context.openFileInput(FILENAME);
}
I am calling this inside the download method
Bitmap downloadBitmap(String url) {
final int IO_BUFFER_SIZE = 4 * 1024;
// AndroidHttpClient is not allowed to be used from the main thread
final HttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
copyInStreamToFile(new FlushedInputStream(inputStream));
DeviceProperties device = new DeviceProperties(activity);
return decodeBitampFromResource(device.getDeviceHeight(),
device.getDeviceWidth());
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
and the last method which makes the decoding is this:
public static Bitmap decodeBitampFromResource(int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
FileInputStream fis;
InputStream is;
Bitmap bitmap = null;
// kanonika tha vriskei to megethos tis photo alla kapoio problima
// iparxei me ton sixronismo
try {
fis = getStream();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(fis, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
fis.close();
fis = getStream();
bitmap = BitmapFactory.decodeStream(fis, null, options);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
Do I have to clear the content of the file-output-stream? As I know from android developers openFileOutput opens the file and override it's content or creates it if it doesn't exist.
Related
I'm using Volley library in my project but I have problem with OutOfMemory Exception. In my application I'm downloading thumbs and full size images from server via NetworkImageView using setImageUrl method. I'm using BitmapLruCache:
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public BitmapLruCache() {
this(getDefaultLruCacheSize());
}
public BitmapLruCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
#Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
#Override
public Bitmap getBitmap(String url) {
return get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
I'm getting OutOfMemoryException on HTC Desire (Android 2.2.2). How can I deal with this exception? Is something wrong I'm doing?
Edit
This exception I got during monkey test:
java.lang.OutOfMemoryError at
com.android.volley.toolbox.ByteArrayPool.getBuf(ByteArrayPool.java:101)
at
com.android.volley.toolbox.PoolingByteArrayOutputStream.expand(PoolingByteArrayOutputStream.java:76)
at
com.android.volley.toolbox.PoolingByteArrayOutputStream.write(PoolingByteArrayOutputStream.java:84)
at
com.android.volley.toolbox.BasicNetwork.entityToBytes(BasicNetwork.java:213)
at
com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:104)
at
com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:105)
#Sipka - it doesn't solve my problem
#Muhammad Babar - Volley library handles all network/bitmap/cache operations so I need solution to fix OutOfMemory exception caused by Volley.
Use this code to create Bitmap in a thread that will help you
Bitmap bitmap = null;
HttpResponse response = null;
InputStream instream = null;
try {
File file = new File(Environment.getExternalStorageDirectory()
.toString(), floderName);
String s = file.getAbsolutePath();
f = new File(s);
if (!f.exists()) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(new URL(url[0]).toURI());
response = client.execute(request);
if (response.getStatusLine().getStatusCode() != 200) {
return null;
}
// BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
// response.getEntity());
instream = response.getEntity().getContent();
OutputStream os = new FileOutputStream(f);
Globals.CopyStream(instream, os);
os.close();
instream.close();
}
FileInputStream fs = null;
try {
fs = new FileInputStream(f);
} catch (FileNotFoundException e) {
// TODO do something intelligent
e.printStackTrace();
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inDither = false; // Disable Dithering mode
o2.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
o2.inInputShareable = true; // Which kind of reference will be used
// to recover the Bitmap data after
// being clear, when it will be used in
// the future
o2.inTempStorage = new byte[32 * 1024];
o2.inSampleSize = 1;
bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, o2);
bit = bitmap;
// bit.compress(Bitmap.CompressFormat.JPEG, 90, null);
newsFeed.setBitmap(bit);
// Data.globelCoverIcon = bit;
// OutputStream os = new FileOutputStream(f);
} catch (Exception ex) {
ex.printStackTrace();
}
public class Globals {
private static final int JPEG_EOI_1 = 0xFF;
private static final int JPEG_EOI_2 = 0xD9;
public static void CopyStream(InputStream is, OutputStream os) {
final int buffer_size = 1024;
try {
byte[] bytes = new byte[buffer_size];
for (;;) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
} catch (Exception ex) {
Log.e("App", ex.getMessage(), ex);
}
}
}
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;
}
}
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.
I am using the code below in asyn task to download a bitmap to be added to my custom class. however sometimes it return nulls with no IOException or any exception. i am not very sure what can be done
public Bitmap downloadFile(String fileUrl){
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
//conn.setReadTimeout(500000000);
conn.connect();
InputStream is = conn.getInputStream();
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, o);
is.close();
conn.disconnect();
int scale = 1;
int IMAGE_MAX_SIZE=400;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
//conn.setReadTimeout(500000000);
conn.connect();
is = conn.getInputStream();
Bitmap b = BitmapFactory.decodeStream(is, null, o2);
if (b==null)
Log.e(Config.log_id, " Download image failed");
return b;
}
catch (IOException e) {
Log.e(Config.log_id, " Download image failed"+e.getMessage());
e.printStackTrace();
}
return null;
}
I have run into this as well when using unbuffered variants of
stream readers when getting from urls.
The simple solution that worked for me was to use a BufferedHttpEntity to get the image data.
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
public static Bitmap decodeFromUrl(HttpClient client, URL url, Config bitmapCOnfig)
{
HttpResponse response=null;
Bitmap b=null;
InputStream instream=null;
BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
decodeOptions.inPreferredConfig = bitmapCOnfig;
try
{
HttpGet request = new HttpGet(url.toURI());
response = client.execute(request);
if (response.getStatusLine().getStatusCode() != 200)
{
MyLogger.w("Bad response on " + url.toString());
MyLogger.w ("http response: " + response.getStatusLine().toString());
return null;
}
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(response.getEntity());
instream = bufHttpEntity.getContent();
return BitmapFactory.decodeStream(instream, null, decodeOptions);
}
catch (Exception ex)
{
MyLogger.e("error decoding bitmap from:" + url, ex);
if (response != null)
{
MyLogger.e("http status: " + response.getStatusLine().getStatusCode());
}
return null;
}
finally
{
if (instream != null)
{
try {
instream.close();
} catch (IOException e) {
MyLogger.e("error closing stream", e);
}
}
}
}
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;
}