Android decoder-> decode возвратил false для загрузки растрового изображения - PullRequest
27 голосов
/ 02 декабря 2010

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

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

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

Ответы [ 7 ]

33 голосов
/ 28 декабря 2010

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

и вот, пожалуйста ... теперь у вас не будет никаких проблем.

10 голосов
/ 21 января 2011

Вот способ, который работал для меня:

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);
5 голосов
/ 04 января 2013

Исходный код из этого 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(), которое выполняется в потоке пользовательского интерфейса, и оно больше не будет работать, выдавая мне ту же ошибку.

2 голосов
/ 18 февраля 2011

Вот способ, который сработал для меня:

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

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

1 голос
/ 06 декабря 2013

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

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

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

1 голос
/ 29 ноября 2012

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

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

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

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

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

0 голосов
/ 27 июня 2016

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...