wie Bitmap-Informationen zu erhalten und dann Bitmap von Internet-InputStream zu dekodieren?

9

Hintergrund

Angenommen, ich habe einen InputStream, der aus dem Internet einer bestimmten Image-Datei stammt.

Ich möchte Informationen über die Bilddatei erhalten und erst dann entschlüsseln.

Es ist nützlich für mehrere Zwecke, wie Downsampling und Vorschau der Informationen, bevor das Bild angezeigt wird.

das Problem

Ich habe versucht, den InputStream zu markieren und zurückzusetzen, indem ich den inputStream mit einem BufferedInputStream umhüllte, aber es hat nicht funktioniert:

%Vor%

Um den InputStream aus einer URL heraus zu bekommen, benutze ich:

%Vor%

die Frage

Wie kann ich den Code behandeln die Markierung ein Reset?

es funktioniert perfekt mit Ressourcen (tatsächlich musste ich nicht einmal einen neuen BufferedInputStream erstellen, damit das funktioniert), aber nicht mit inputStream aus dem Internet ...

BEARBEITEN:

es scheint, mein Code ist in Ordnung, irgendwie ...

auf einigen Websites (wie diesem und dieser ), es kann die Bilddatei auch nach dem Zurücksetzen nicht dekodieren.

Wenn Sie die Bitmap dekodieren (und inSampleSize verwenden), kann sie es gut dekodieren (dauert nur sehr lange).

Jetzt ist die Frage, warum es passiert, und wie kann ich es beheben.

    
android developer 21.07.2013, 16:29
quelle

4 Antworten

0

Ich glaube, das Problem ist, dass der Aufruf von mark () mit dem großen Wert durch einen Aufruf überschrieben wird (1024). Wie in der Dokumentation beschrieben:

Wenn is.markSupported () vor KITKAT den Wert true zurückgibt, wird is.mark (1024) aufgerufen. Ab KITKAT ist dies nicht mehr der Fall.

Dies kann dazu führen, dass ein Reset () fehlschlägt, wenn Lesevorgänge ausgeführt werden, die größer als dieser Wert sind.

    
hdante 18.01.2014 22:26
quelle
0

( Hier ist eine Lösung für das gleiche Problem, aber beim Lesen von der Festplatte. Ich habe nicht bemerkt, zuerst Ihre Frage wurde speziell aus einem Netzwerk-Stream. )

Das Problem mit mark & ​​amp; Im Allgemeinen wird hier zurückgesetzt, dass BitmapFactory.decodeStream() manchmal Ihre Marken zurücksetzt. Somit ist das Zurücksetzen, um das tatsächliche Lesen durchzuführen, unterbrochen.

Aber es gibt ein zweites Problem mit BufferedInputStream: Es kann dazu führen, dass das gesamte Bild im Speicher gepuffert wird, unabhängig davon, wo Sie es gerade lesen. Abhängig von Ihrem Anwendungsfall kann dies Ihre Leistung beeinträchtigen. ( Viel Zuteilung bedeutet viel GC )

Hier gibt es eine wirklich gute Lösung: Ссылка

Ich habe es für diesen speziellen Anwendungsfall leicht modifiziert, um das Mark & ​​amp; Problem zurücksetzen:

%Vor%

Dies wird während Lesevorgängen keinen zusätzlichen Speicher zuweisen und kann zurückgesetzt werden, selbst wenn die Markierungen gelöscht wurden.

    
Adam 03.06.2014 18:52
quelle
-1

Ob Sie einen Stream markieren / zurücksetzen können, hängt von der Implementierung des Streams ab. Dies sind optionale Operationen und werden normalerweise nicht unterstützt. Ihre Optionen sind, den Stream in einen Puffer zu lesen und dann von diesem Stream 2x zu lesen, oder einfach die Netzwerkverbindung 2x zu machen.

Die einfachste Sache ist wahrscheinlich, in eine ByteArrayOutputStream zu schreiben,

%Vor%

verwende jetzt entweder direkt das Ergebnis von baos.toByteArray() , oder erstelle ein ByteArrayInputStream und benutze das wiederholt und rufe reset() nach jedem Aufruf auf.

%Vor%

das klingt vielleicht albern, aber es gibt keine Magie. Sie puffern entweder die Daten im Speicher, oder Sie lesen es 2x von der Quelle. Wenn der Stream mark / reset unterstützt, müsste er dasselbe in seiner Implementierung tun.

    
Jeffrey Blattman 21.07.2013 16:37
quelle
-1

Hier ist eine einfache Methode, die immer für mich funktioniert:)

%Vor%     
Marcus Gabilheri 03.06.2014 19:13
quelle

Tags und Links