BitmapFactory.decodeStream gibt immer null und skia Decoder zeigt wieder falsch dekodieren

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

  •  25-09-2019
  •  | 
  •  

Frage

Testbild hier: http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gif

Ich habe versucht, mehr Lösungen gefunden im Internet, aber es gibt keine funktionierende Lösung.

Ich bin mit dem folgenden Snippet-Code:

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

Immer dieses Protokoll erhalten:

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

Jede Hilfe? Danke.

EDIT:

ist fehlgeschlagen Diese Bilder decodiert werden sollen, können auch nicht auf einem WebView gezeigt werden. Aber kann in einem Browser, wenn offen sehen.

War es hilfreich?

Lösung

Versuchen Sie dies als eine vorübergehende Lösung:

Sie zuerst die folgende Klasse hinzu:

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

}

Dann wickeln Sie Ihren ursprünglichen Strom mit PlurkInputStream:

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

Lassen Sie mich wissen, ob das Ihnen hilft.

EDIT:

Leider versuchen Sie bitte die folgende Version statt:

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

Beachten Sie, dass dies nicht effizienten Code ist noch ist dies eine voll / richtige Lösung. Es wird in den meisten Fällen funktionieren, aber nicht alle.

Andere Tipps

Ich hatte das gleiche Problem, teilweise von dieser Klasse nicht festgelegt wurde:

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

}

Und:

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

Es half in den meisten Fällen, aber dies ist nicht universelle Lösung. Weitere hierzu finden Sie bugreport .

Best Glück!

Ich habe versucht, alle Lösungen aber hat mein Problem nicht gelöst. Nach einigen Tests, eine Menge passiert ist das Problem der skia Decoder failing, wenn die Internet-Verbindung nicht stabil ist. Für mich zwingen, das Bild löste das Problem erneut herunterladen.

Das Problem auch mehr präsentiert, wenn das Bild der großen Größe ist.

Mit einer Schleife erforderlich ich höchstens 2 Wiederholungen und das Bild wird korrekt heruntergeladen werden.

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

Dies sollte funktionieren:

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 enthält Ihr Bild.

Das ist aufgrund eines Fehlers in der Input Klasse in Android. Sie können eine gültige Abhilfe und eine Beschreibung des Fehlers finden hier http: // code.google.com/p/android/issues/detail?id=6066

Aus Speichergründen müssen Sie wie folgt implementiert BitmapFactory Optionen sein:

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

Die Haupt-Download-Bitmap-Funktion vielleicht wie folgt aus:

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

Und vielleicht müssen Sie Geräte AsyncTask so aussehen: http://android-developers.blogspot.com/2010/07 /multithreading-for-performance.html

Für mich ist das Problem mit der Art der Farbe des Bildes: Ihr Bild in Farbe = CYMK nicht in RGB

Vielleicht ist das nicht Ihr Fall, aber es könnte sein, wenn Sie zu dekodieren Bildern mit CMYK-Farbraum versuchen, anstelle von RGB-Farbraum. CMYK-Bilder, wie diese , werden nicht von Android unterstützt, und wird nicht angezeigt, selbst in der Android Web-Browser. Lesen Sie mehr über diese hier :

Unable JPEG-Bild mit BitmapFactory zu laden. decodeFile. Returns null

Versuchen Sie diese:

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top