Ich muss ein Bild skalieren, bevor ich es erstelle, und ich möchte es nur dann machen, wenn es 1024 KB (zum Beispiel) überschreitet.
Wenn ich Folgendes tue, kann ich das Bild skalieren, aber ich muss nur diejenigen skalieren, die größer als die angegebene Größe sind.
%Vor%Wie kann ich die Größe der Bitmap erhalten? (Ich bin froh, die Menge an Bytes zu kennen, nicht die Größe nach dem Dekomprimieren).
Bearbeiten:
Ich versuche das:
%Vor%Das erste Mal, dass ich InputStream (is) verwende, um es mit "inJustDecodeBounds" zu dekodieren, funktioniert gut und ich kann die Bitmap-Dimensionen bekommen. Das Problem ist, dass das zweite Mal, wenn ich es benutze, um das Bild tatsächlich zu decodieren, kein Bild gezeigt wird.
Was mache ich falsch?
Ich bin ein Noob, also kann ich die Antwort von moonjack nicht direkt kommentieren. Der Grund, warum seine Antwort so langsam ist, ist, dass es ein Byte nach dem anderen kopiert. Die Verwendung eines Puffers von sogar 1K wird die Leistung erheblich verbessern.
%Vor%Wenn Sie das Format der Datei kennen, können Sie den Header der Datei lesen. Normalerweise enthält die Kopfzeile die Größe und das Format des Bildes. Und zum Glück für Sie, das sind immer die ersten Bytes der Datei.
Bei bestimmten Typen ist dies möglicherweise nicht möglich.
Lesen Sie einfach über den Header und einige Dateien, die Sie möglicherweise zuerst die Breite erraten müssen. Zum Beispiel scheint das PNG keine Breite / Höhe zu enthalten, aber Sie sollten in der Lage sein, die Breite zu lesen und eine Höhe mit der Pixelgröße zu schätzen.
Bearbeiten: Mein schlechtes Ich dachte, Sie wollten mit der Dimension skalieren ... Yeah ContentLength sollte helfen, aber manchmal wird 0 zurückgeben, wenn der Server nicht die richtige Dimension in der HTTP-Header festgelegt. In diesem Fall müssen Sie die zurückgegebene Größe kennen. Wie auch immer, Sie können ein Bytearray speichern und wenn alles geladen ist, überprüfen Sie einfach die Länge des Arrays. Wenn es größer als 1024 KB ist, ändern Sie die Größe des Bildes. Und speichern Sie es oder machen Sie damit, was Sie wollen.
Sie können is
mit einem new BufferedInputStream(is);
umbrechen und die Methoden mark(int readlimit)
und reset()
verwenden, um den Stream erneut zu lesen. Sie müssen entscheiden, was readlimit
eingestellt werden soll, damit es den gesamten Header lesen kann. Die von Loïc bereitgestellten Links sollten hier helfen.
Ich habe eine geeignete Fehlerbehandlung für die reset()
-Methode weggelassen, es wird IOException
geworfen, wenn Sie mehr als readlimit
bytes aus dem Stream gelesen haben.
Wenn Sie versuchen OutOfMemory oder etwas anderes zu verhindern ...
Sie können einen Puffer mit Ihren Bilddaten erstellen,
%Vor%Dann können Sie die Größe mit buffer.outHeight, buffer.outWidth ..
erhaltenWenn Sie skalieren möchten, verwenden Sie einfach buffer.isSampleSize, aber ich habe bemerkt, dass Sie dort einen "10" -Wert setzen ... was ich denke, ist falsch ... sampleSize sollte einen 2 ^ Wert erhalten .. wie 2 , 4,8,16 usw.
Schließlich, nachdem Sie die Einstellung sampleSize haben, können Sie die Bitmap wie immer erstellen.
%Vor%hoffe, Ihnen zu helfen!
PS: SQS MEIN ENGLISCH = (!!!
Sie können die Größe eines Streams nicht durch seine Definition bestimmen. Wenn Sie möchten, können Sie den Stream in ein Byte-Array laden, um die Byte-Anzahl daraus zu ermitteln. Sie können die BitmapFactory auch verwenden, um ein Byte-Array direkt zu dekodieren, so dass das ganz gut funktioniert.
%Vor%Die meisten Streams werden verbraucht, wenn Sie von ihnen lesen. In Ihrem zweiten Codeblock konsumieren Sie den Stream das erste Mal als Bitmap. Wenn Sie decodeString ein zweites Mal aufrufen, ist der Stream "leer" (wenn nur in dem Sinne, dass alle Daten bereits gelesen wurden).
Die beste Antwort wird wahrscheinlich die von Monkjack sein, aber vielleicht mit ein wenig extra Code, um sicherzustellen, dass Sie keine gigantische Datei in den Speicher lesen. Ich empfehle nur eine Überprüfung, wie Sie es in einen Puffer für die Größe streamen (d. H. Bei 10 MB stoppen); Ich bin mir nicht sicher, wie gut Android mit einer Ausnahme wegen zu wenig Speicher umgehen kann.
Wenn Sie ein Downscaling durchführen, um OutOfMemoryException
wie mich zu verhindern, kann diese Lösung für Sie besser funktionieren (aufbauend auf den Antworten hier):
Ich habe die Verwendung von mark(int)
und reset()
vermieden, weil es in meinem Fall keine Obergrenze für die Größe des Streams gibt. Wie Sie den Stream zurücksetzen, hängt von Ihrer Implementierung ab. Mein Stream wurde mit Uri
angegeben, also habe ich einfach Folgendes verwendet:
um den Stream zurückzusetzen.
Überprüfen Sie logcat, wenn Sie einen Fehler haben, der "Bitmap too large to be uploaded into a texture"
sagt, dann müssen Sie Folgendes tun. Meine Antwort ist ähnlich wie @Sergio A. aber Sie können BitmapFactory.decodeStream direkt anstelle von decodeByteArray verwenden.
Dies wird nur die Größe des Bildes (nicht das ganze Bild selbst) erhalten. Sie können die Breite und Höhe mit dem folgenden Code isolieren.
%Vor% Sie können diese Werte (zusammen mit Ihrer gewünschten Breite und Höhe - höchstwahrscheinlich basierend auf der imageView oder dem Bildschirm) verwenden, um options.inSampleSize
zu berechnen. Ich werde nicht darauf eingehen, wie das geht, aber Google hat ein Tutorial hier .
Hoffe das hilft:)
Sie können nicht die Größe einer Bitmap erhalten, da ist einfach kein eingebauter Weg. Sie können jedoch die Größe des Inhalts (einer Datei) ermitteln, was Sie wahrscheinlich tun müssen. So etwas sollte funktionieren.
%Vor%Tags und Links android