BitmapFactory.Decodestream sempre retorna NULL e SKIA Decoder Shows Decode retornados falsos

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

  •  25-09-2019
  •  | 
  •  

Pergunta

Imagem de teste aqui:http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gif

Eu tentei várias soluções encontradas na Internet, mas não há solução de trabalho.

Estou usando o seguinte código de snippet:

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

Sempre recebendo este log:

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

Qualquer ajuda? Obrigado.

EDITAR:

Essas imagens não foram decodificadas também não podem ser mostradas em um WebView. Mas pode ver se aberto em um navegador.

Foi útil?

Solução

Experimente isso como uma solução alternativa temporária:

Primeiro, adicione a aula a seguir:

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

}

Em seguida, embrulhe seu fluxo original com PlurkinputStream:

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

Deixe-me saber se isso o ajuda.

EDITAR:

Desculpe, por favor, tente a seguinte versão:

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

Observe que este não é um código eficiente nem é uma solução completa/correta. Funcionará para a maioria dos casos, mas não todos.

Outras dicas

Eu tive o mesmo problema, parcialmente foi corrigido por esta 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;
}

}

E:

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

Ajudou na maioria dos casos, mas isso não é uma solução universal. Para mais, consulte isso relatório de erro.

Boa sorte!

Eu tentei todas as soluções, mas não resolvi meu problema. Após alguns testes, o problema da falha do decodificador da SKIA aconteceu muito quando a conexão com a Internet não é estável. Para mim, forçando a redução da carga, a imagem resolveu o problema.

O problema também apresentou mais quando a imagem é de tamanho grande.

O uso de um loop me exigirá no máximo duas tentativas e a imagem será baixada corretamente.

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

Isso deve funcionar:

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 contém sua imagem.

Isso se deve a um bug na classe InputStream no Android. Você pode encontrar uma solução alternativa válida e uma descrição do bug aqui http://code.google.com/p/android/issues/detail?id=6066

Por razões de memória, você deve implementar opções de bitmapfactory como esta:

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

A principal função de download de bitmap talvez seja assim:

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

E talvez você deva estar implementa a assínceta como esta:http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

Para mim, o problema é com o tipo de cor da imagem: sua imagem está em cor = cymk não em rgb

Talvez este não seja o seu caso, mas pode ser se você estiver tentando decodificar imagens com espaço de cores CMYK, em vez do espaço de cores RGB. Imagens cmyk, como Este, não são suportados pelo Android e não serão exibidos mesmo no navegador da Web Android. Leia mais sobre isso aqui:

Incapaz de carregar jpeg-image com bitmapFactory.DecodeFile. Retorna nulo

Experimente isso:

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top