2010-09-27 20 views
3

ici: http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gifBitmapFactory.decodeStream retourne toujours décodeur nul et skia montre decode retourné image test faux

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 pas figurer sur un WebView. Mais peut voir si ouvert dans un navigateur.

Répondre

4

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

} 

envelopper ensuite votre flux original avec PlurkInputStream :

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

Faites-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. Cela fonctionnera dans la plupart des cas, mais pas tous.

+0

Merci de votre aide, mais obtenez toujours le même résultat. 10-28 18: 36: 03.970: DEBUG/skia (14676): --- décodeur-> décodage renvoyé faux 10-28 18: 36: 03.970: ERREUR: l'image est nulle. http://images.plurk.com/tn_5606289_30342c409d2a5a5cd747e064721464c4.gif – shiami

+0

Je suis curieux de savoir pourquoi vous remplacez la méthode à cela? – shiami

+0

Android skia decoder fait ce que l'on appelle un contrôle TopLeft sur les dimensions gif et ne gère pas les images qui sortent des limites de la toile. En remplaçant la méthode de lecture, nous remplaçons le décalage de dessin par rapport à la toile à zéro et trompons le décodeur skia pour accepter le fichier gif pour un décodage ultérieur. Vous pouvez regarder dans le code source Skia pour Android et faire un bvi vérifier sur les images par rapport à la spécification GIF89a. –

0

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.

+0

Merci, mais ne fonctionne toujours pas. Il retourne toujours nul. Une autre image de test: http://images.plurk.com/tn_5018722_bf926743319e0ed15ccbab52a114900a.gif – shiami

4

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

}

Et:

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 la solution universelle . Pour plus d'informations, référez-vous à bugreport.

Bonne chance!

+0

J'ai essayé cela et aussi ne fonctionne pas – shiami

0

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

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

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 peut-être que vous devez implémenter AsyncTask comme ceci: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

1

J'ai essayé toutes les solutions, mais n'a pas résolu mon problème. Après quelques tests, le problème de l'échec du décodeur skia est survenu beaucoup lorsque la connexion internet n'est pas stable. Pour moi, forcer à télécharger l'image a résolu le problème.

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

L'utilisation d'une boucle me demandera au plus 2 tentatives et l'image sera téléchargée correctement.

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

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

0

Peut-être que ce n'est pas votre cas, mais il pourrait être si vous essayez de décoder les images avec l'espace colorimétrique CMJN, au lieu de l'espace colorimétrique RVB. Les images CMJN, telles que this one, ne sont pas prises en charge par Android et ne seront pas affichées même dans le navigateur Web Android. En savoir plus sur ce here:

Unable to load JPEG-image with BitmapFactory.decodeFile. Returns null