Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progressive jpeg on Android [duplicate]

I've started getting a

DEBUG/skia(xxxx): --- decoder->decode returned false 

issue on a few profile images from Facebook that I use in ImageViews. Most work perfectly, but every once in a while I discover one that never works.

I am compiling my application against Android 1.6 for backward compatibility reasons.

I did some digging and discovered a number of threads on the issue. I'm already using the FlushedInputStream discussed here: http://code.google.com/p/android/issues/detail?id=6066

Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);

Here's an example that's causing me trouble: http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs269.snc3/23132_639284607_390_q.jpg

Can someone check out the image and help me figure out what's causing the trouble?

like image 591
Richard Avatar asked Dec 02 '10 19:12

Richard


4 Answers

There is a bug in FlushedInputStream(is). it fails on slow connections but you can try my magical code to fix it.

Bitmap b = BitmapFactory.decodeStream(new FlushedInputStream(is));
imageView.setImageBitmap(b);

create a static class outside your method

 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 b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

and here you go.. now you will not have any problem.

like image 110
AZ_ Avatar answered Dec 04 '22 23:12

AZ_


Here is a way that worked for me:

HttpGet httpRequest = new HttpGet(url);
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
//Bitmap b = BitmapFactory.decodeStream(is);
like image 43
Vikas Avatar answered Dec 04 '22 22:12

Vikas


The source code from this ImageDownloader.java is a good orientation. It has a bug fix which addresses the Issue 6066 by providing a patched FlushedInputStream class.

Another thing which you might want to take care of, is to execute the decoding in the same thread as the HTTP request was executed:

@Override
protected Bitmap doInBackground(String... url) {
     // execute HTTP GET request and decode response
     ...
     return bitmap
}


@Override
protected void onPostExecute(Bitmap result) {
     imageView.setImageBitmap(result);
}

I had done the decoding in the onPostExecute(), which is executed in the UI thread, and it would not work anymore, giving me the same error.

like image 30
Konrad Reiche Avatar answered Dec 04 '22 23:12

Konrad Reiche


Here is a way that worked for me:

public static Bitmap loadImageFromUrl(String url) {
        URL m;
        InputStream i = null;
        BufferedInputStream bis = null;
        ByteArrayOutputStream out =null;
        try {
            m = new URL(url);
            i = (InputStream) m.getContent();
            bis = new BufferedInputStream(i,1024 * 8);
            out = new ByteArrayOutputStream();
            int len=0;
            byte[] buffer = new byte[1024];
            while((len = bis.read(buffer)) != -1){
                out.write(buffer, 0, len);
            }
            out.close();
            bis.close();
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] data = out.toByteArray();
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        //Drawable d = Drawable.createFromStream(i, "src");
        return bitmap;
    }

I loaded the image by multithreading, and then I had to loop reading the inputStream when the thread's time was held by another. Make sure the inputStream is read fully.

like image 32
getmsg Avatar answered Dec 04 '22 23:12

getmsg