Подтвердить что ты не робот

Android-декодер-> декодирование возвращено false для Bitmap download

Я начал получать

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

выведите несколько изображений профиля из Facebook, которые я использую в ImageViews. Большинство работает отлично, но время от времени я обнаруживаю тот, который никогда не работает.

Я компилирую свое приложение против Android 1.6 для обеспечения обратной совместимости.

Я немного поработал и обнаружил несколько потоков в этом вопросе. Я уже использую FlushedInputStream, обсуждаемый здесь: http://code.google.com/p/android/issues/detail?id=6066

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

Вот пример, который вызывает у меня проблемы: http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs269.snc3/23132_639284607_390_q.jpg

Может кто-нибудь проверить изображение и помочь мне выяснить, что вызывает проблемы?

4b9b3361

Ответ 1

В FlushedInputStream (есть) есть ошибка. он не работает при медленных соединениях, но вы можете попробовать мой магический код, чтобы исправить его.

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

создать статический класс вне вашего метода

 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;
        }
    }

и здесь вы идете.. теперь у вас не будет проблем.

Ответ 2

Вот как это работает для меня:

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);

Ответ 3

Исходный код этого ImageDownloader.java является хорошей ориентацией. У этого есть исправление ошибки, которое адресовано Проблема 6066, предоставив исправленный класс FlushedInputStream.

Еще одна вещь, которую вы, возможно, захотите позаботиться, - выполнить декодирование в том же потоке, что и HTTP-запрос:

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


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

Я выполнил декодирование в onPostExecute(), которое выполняется в потоке пользовательского интерфейса, и оно больше не работает, что дает мне ту же ошибку.

Ответ 4

Вот как это работает для меня:

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;
    }

Я загрузил изображение с помощью многопоточности, а затем мне пришлось зацикливать чтение входного потока, когда время потока удерживалось другим. Убедитесь, что входной поток прочитан полностью.

Ответ 5

Вот что было для меня проблемой:

Из эмулятора я бы сохранил файл jpg локально (на эмулированной SD-карте), а затем попытался его прочитать и отобразить с помощью декодирования на эмуляторе, и он сработал. Затем, в качестве теста, я скопировал файл (с помощью adb pull) на мою машину разработки (xp), и он отобразится с использованием "paint". Затем из эмулятора я загрузил файл (через http post) на мой сервер win2003. Используя "paint", он также отображается там. Но когда я загрузил его обратно в эмулятор (через http get), он потерпел неудачу во время декодирования.

Затем я заметил, что файл, загруженный на сервер win2003, был на два байта меньше оригинала. Не совсем уверен, как это произошло, потому что я использую одну и ту же логику загрузки в течение многих лет и никогда не замечал проблему раньше. В качестве теста я просто добавил еще два случайных байта во время загрузки, поэтому размер файла был точно таким же. Затем, при загрузке обратно в эмулятор, он декодируется и отображается правильно.

Так же, как проверка, я добавил два случайных байта в мои проекты xcode, а затем эти файлы jpg также отображались на эмуляторе Android.

Итак, хотя файлы, которые были на два байта меньше отображались везде, они не были бы на эмуляторе. По-видимому, декодирование делает какой-то CRC, прежде чем он попытается декодировать и решает, что он не может продолжаться. И, следовательно, ошибка.

Ответ 6

Другие, столкнувшиеся с проблемами в Android KitKat 4.4, будут полезны

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

Я столкнулся с этой проблемой в серии Nexus. После обновления до 4.4.

Ответ 7

Я столкнулся с этой проблемой, используя Xamarin. Чтобы исправить это, я просто использовал Universal Image Loader Xamarin Component и работал как шарм.

Надеюсь, это поможет!