BitmapFactory.decodeStream retourne toujours nul et décodeur skia montre decode retourne faux

StackOverflow https://stackoverflow.com/questions/3802820

  •  25-09-2019
  •  | 
  •  

Question

image test ici: http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gif

J'ai essayé plusieurs solutions trouvées sur Internet, mais il n'y a pas de solution de travail.

J'utilise le fragment de code suivant:

Url imageUrl = new Url("http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gif");
Bitmap image = BitmapFactory.decodeStream(imageUrl.openStream());

Toujours obtenir ce journal:

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

Toute aide? Merci.

EDIT:

Ces images ont échoué à décoder sont également ne peuvent être affichées sur un WebView. Mais peut voir si elle est ouverte dans un navigateur.

Était-ce utile?

La solution

Essayez cela comme une solution temporaire:

Ajoutez d'abord la classe suivante:

  public static class PlurkInputStream extends FilterInputStream {

    protected PlurkInputStream(InputStream in) {
        super(in);
    }

    @Override
    public int read(byte[] buffer, int offset, int count)
        throws IOException {
        int ret = super.read(buffer, offset, count);
        for ( int i = 2; i < buffer.length; i++ ) {
            if ( buffer[i - 2] == 0x2c && buffer[i - 1] == 0x05
                && buffer[i] == 0 ) {
                buffer[i - 1] = 0;
            }
        }
        return ret;
    }

}

Ensuite, enveloppez votre flux original avec PlurkInputStream:

Bitmap bitmap = BitmapFactory.decodeStream(new PlurkInputStream(originalInputStream));

Laissez-moi savoir si cela vous aide.

EDIT:

Désolé s'il vous plaît essayer la version suivante à la place:

        for ( int i = 6; i < buffer.length - 4; i++ ) {
            if ( buffer[i] == 0x2c ) {
                if ( buffer[i + 2] == 0 && buffer[i + 1] > 0
                    && buffer[i + 1] <= 48 ) {
                    buffer[i + 1] = 0;
                }
                if ( buffer[i + 4] == 0 && buffer[i + 3] > 0
                    && buffer[i + 3] <= 48 ) {
                    buffer[i + 3] = 0;
                }
            }
        }

Notez que ce n'est pas efficace, ni le code est-ce une solution complète / correcte. Il fonctionnera pour la plupart des cas, mais pas tous.

Autres conseils

J'ai eu le même problème, en partie a été fixé par cette classe:

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

}

InputStream in = null;
    try {
        in = new java.net.URL(imageUrl).openStream();
        } catch (MalformedURLException e) {
        e.printStackTrace();
        } catch (IOException e) {
        e.printStackTrace();
        }
Bitmap image = BitmapFactory.decodeStream(new FlushedInputStream(in));

Il a aidé dans la plupart des cas, mais ce n'est pas de solution universelle. Pour en savoir plus consulter cette bugreport.

Meilleure chance!

J'ai essayé toutes les solutions, mais n'a pas résolu mon problème. Après quelques essais, le problème du défaut de décodeur skia passé beaucoup lorsque la connexion Internet est pas stable. Pour moi, ce qui oblige à retélécharger l'image a résolu le problème.

Le problème a également présenté plus lorsque l'image est de grande taille.

En utilisant une boucle me sera nécessaire au plus 2 et l'image retries sera téléchargé correctement.

Bitmap bmp = null;
int retries = 0;
while(bmp == null){
    if (retries == 2){
        break;
    }
    bmp = GetBmpFromURL(String imageURL);
    Log.d(TAG,"Retry...");
    retries++;
}

Cela devrait fonctionner:

URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
connection.disconnect();
input.close();

myBitmap contient votre image.

cela est dû à un bogue dans la classe InputStream dans Android. Vous pouvez trouver une solution de contournement valide et une description du bug ici http: // code.google.com/p/android/issues/detail?id=6066

Pour des raisons de mémoire, vous devez être des outils BitmapFactory options comme ceci:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; // might try 8 also

La fonction principale bitmap de téléchargement peut-être comme ceci:

Bitmap downloadBitmap(String url) {

    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) {
            if(DEBUG)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();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 4; // might try 8 also
                return BitmapFactory.decodeStream(new FlushedInputStream(inputStream),null,options);

            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                entity.consumeContent();
            }
        }
    } catch (IOException e) {
        getRequest.abort();
        if(DEBUG)Log.w(TAG, "I/O error while retrieving bitmap from " + url, e);
    } catch (IllegalStateException e) {
        getRequest.abort();
        if(DEBUG)Log.w(TAG, "Incorrect URL: " + url);
    } catch (Exception e) {
        getRequest.abort();
        if(DEBUG)Log.w(TAG, "Error while retrieving bitmap from " + url, e);
    } finally {
        if ((client instanceof AndroidHttpClient)) {
            ((AndroidHttpClient) client).close();
        }
    }
    return null;
}

Et vous devez peut-être être des outils AsyncTask comme ceci: http://android-developers.blogspot.com/2010/07 /multithreading-for-performance.html

Pour moi, le problème est avec le type de couleur de l'image: l'image est en couleur = CMYK pas RGB

Peut-être que ce n'est pas votre cas, mais il pourrait être si vous essayez de décoder des images avec CMJN colorspace, au lieu de RVB colorspace. images CMJN, comme celui-ci , ne sont pas pris en charge par Android, et ne seront pas affichés même dans le navigateur web d'Android. En savoir plus sur cette :

JPEG Impossible de charger l'image avec BitmapFactory. decodeFile. Retourne null

Essayez ceci:

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);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top