Wie zu verwenden JNI bitmap-Operationen zu helfen, zu vermeiden, OOM bei großen Bildern?

Hintergrund

meisten der Zeit, immer OOM auf android ist durch die Verwendung von zu viele bitmaps und/oder erstellen von großen bitmaps.

vor kurzem habe ich beschlossen, zu versuchen, JNI, um zu ermöglichen, die Vermeidung von OOM durch die Speicherung der Daten selbst auf die JNI-Seite.

nach Herumspielen mit JNI für eine Weile, ich habe einige Beiträge auf SO um Hilfe zu bitten und mein wissen teilen, und nun habe ich beschlossen, zu teilen einige weitere code mit Sie. hier sind die Beiträge, falls es jemanden interessiert bei der Lektüre der Ergebnisse oder dazu beitragen :

dieser Zeit, die ich Hinzugefügt habe, die Fähigkeit,zu speichern, wiederherzustellen, zuschneiden und drehen von bitmaps. es sollte einfach mehr Optionen und ich würde glücklich sein, wenn andere Menschen, die hier fügen Sie Ihren eigenen code, um weitere nützliche Funktionen .

also der code, den ich jetzt zeigen werde, ist eigentlich die Verschmelzung von all den Dingen, die ich angelegt habe.

Beispielcode der Nutzung:

Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
final int width=bitmap.getWidth(),height=bitmap.getHeight();
//store the bitmap in the JNI "world"
final JniBitmapHolder bitmapHolder=new JniBitmapHolder(bitmap);
//no need for the bitmap on the java "world", since the operations are done on the JNI "world"
bitmap.recycle();
//crop a center square from the bitmap, from (0.25,0.25) to (0.75,0.75) of the bitmap.
bitmapHolder.cropBitmap(width/4,height/4,width*3/4,height*3/4);
//rotate the bitmap:
bitmapHolder.rotateBitmapCcw90();
//get the output java bitmap , and free the one on the JNI "world"
bitmap=bitmapHolder.getBitmapAndFree();

Das Projekt ist auf github

  • Projekt-Seite ist verfügbar auf github hier .

  • fühlen Sie sich frei zu geben, berät und beitragen.

Wichtige Hinweise

gleichen Noten wie gezeigt hier, plus:

  • aktuellen Funktionen geschrieben werden, die hier (mehr aktualisiert auf der Seite des Projektes) :

    • store

    • wiederherstellen

    • drehen Sie 90 Grad gegen den UZS

    • Ernte.

  • den Ansatz, den ich genommen habe für diesen code ist sowohl Speicher-Effizienz (verwenden Sie nur Speicher, den ich brauche, und frei, wenn Sie nicht benötigt), und die CPU-Effizienz (ich habe versucht, Pointer und CPU-memory-cache-Optimierungen, Wann immer möglich).

  • für die beste Leistung, die ich getan habe wirklich einige Validierungen, insbesondere auf die JNI-Teil. es könnte sein, am besten zu verwalten Validierungen auf der java "Welt".

  • gibt es noch viele fehlt Funktionen, die ich denke sollte Hinzugefügt werden, und ich hoffe, dass ich die Zeit, um Sie hinzuzufügen . wenn wer beitragen möchte, werde ich froh sein, fügen Sie code zu. hier sind die Funktionen, die ich denke, könnte nützlich sein:

    • aktuelle bitmap-info

    • skalieren von bitmaps, einschließlich der Wahl des zu verwendenden Algorithmus (nearest neighbour und bilinear interpolation sollte genug sein).

    • verwenden Sie verschiedene bitmap-Formate

    • tun die Decodierung innerhalb von JNI, zu vermeiden, die Schaffung der java-bitmap (und nicht mit dem Haufen auf der java-Welt) am Anfang, nur am Ende, wenn man fertig mit all der Operationen.

    • Gesichtserkennung

    • Drehung in einem beliebigen Winkel, oder zumindest die offensichtlichen . momentan habe ich nur Hinzugefügt, rotation um 90 Grad gegen den Uhrzeigersinn .

  • Ich verstehe nicht, warum Menschen geschlossen haben dieser Frage, wie es soll Menschen helfen, die Handhabung zu große Bilder unter den strengen Richtlinien von Android (kleine heap-Größe). Sie schrieben: "geschlossen, da unklar ist, was Sie Fragen" , obwohl ich bereits erklärt habe eine Menge über ihn und bot eine schöne Lösung, die nützlich sein können für viele Menschen. Wenn Sie eine Frage haben über das, was ich geschrieben habe, schreiben es ab, anstatt downvoting oder schließen . 🙁
  • Hi, ich habe versucht es heraus. Es ist wirklich schön und sehr nützlich. Da ich aber weiß, SO können nur QA-Sitzungen können, warum jemand es geschlossen.
  • ich verstehe es nicht. es ist QA , da andere vielleicht auch helfen bei der Frage und vielleicht sogar eine eigene Lösung. außerdem denke ich, das Frage-und-Antwort könnte hilfreich sein für viele Menschen, da der OOM ist durchaus eine gemeinsame Sache, beim Umgang mit großen Bildern.
  • Ja.. du hast Recht, wir sollten halten Entsendung und Austausch von wissen.
  • ja, ich mag den Austausch von wissen. meiner Meinung nach, wissen sollte geteilt werden, sonst wird es irgendwann "sterben" . closed-source ist etwas, das Sie halten für sich selbst und wird eines Tages verschwunden sein, als ob es nie existierte. natürlich, einige geschlossen, der code ist ok, da es nicht von anderen Unternehmen (zum Beispiel sollten Sie nicht wissen um die Weise habe ich verschlüsselt die gesicherten Daten oder die Art und Weise nenne ich private Server) , aber Allgemeine Lösungen geteilt werden sollte.
  • Hey Hallo .. Wie u tun .. ich habe eine Abfrage. Wie kann ich das Bitmap drehen, was mit C, Weil ich arbeite in der app, wo alle Teile sind in C geschrieben, Also könnten Sie bitte helfen Sie mir, es.
  • ich habe geschrieben, die Umsetzung von rotierenden bitmap um 90 Grad gegen den Uhrzeigersinn. die C-Funktion, die ich gemacht habe nennt sich "jniRotateBitmapCcw90" (voller name ist: "Java_com_jni_bitmap_1operations_jnibitmapholder_jnirotatebitmapccw90" ), während die java-Funktion aufgerufen wird, "rotateBitmapCcw90" . wenn Sie wünschen implementieren Grad-Drehungen, es ist ziemlich ähnlich. für Besondere Grad (12 Grad) , müssen Sie Trigonometrie (cos,sin,...) . wenn Sie Ihre funktionierende Lösung, ich werde gerne einen link (oder den code hier, wenn Sie möchten).
  • Ja, ich habe Durchlaufen. Sie haben geschrieben, die Dinge, die in C++ Weg. Aber in meinem Ende seiner rohen C-codes. Ich bin mit diesem github.com/churnlabs/android-ffmpeg-sample/blob/master/jni/... das dauert frames aus video-und check-Methode Java_com_churnlabs_ffmpegsample_mainactivity_drawframe die schreibt die Pixel einer Bitmap. Ich brauche zu implementieren, die drehen die Dinge hier. Und ehrlich gesagt, ich bin nicht so gut in C/C++, also bitte Sag mir, wie kann die Implementierung Ihres codes hier.
  • C ist sehr ähnlich zu C++ , und der wichtige Teil in dem code für die rotation ist genau das, was pixel zu setzen, wo (loops). in jedem Fall können Sie eine neue Frage und ich werde mein bestes tun, um zu helfen... ich bin eigentlich mehr ein java-Entwickler als C/C++.
  • Dies ist eine sehr nützliche Ressource für die Verwaltung von bitmaps in die und aus der JNI, obwohl ich noch nicht den code ausführen, in die Praxis umzusetzen. Ich denke, einige Leute nicht verstehen, dies als ein QA-da Ihre Frage ist mehr wie eine Erklärung der Funktionen die in der Antwort statt nur eine schlichte Frage. Also, wenn Sie wollen einen Vorschlag zur Verbesserung der QA-Wert dieser Frage eine Möglichkeit könnte sein, lassen Sie einfach das Wesen der Frage (z.B. wie kann ich tun...) und verschieben Sie die Erklärung ein Teil der Antwort zu. Nur so ein Gedanke. Vielen Dank für das teilen dieses nützlichen Informationen.
  • ja, Sie haben einen Punkt, aber ich habe auch nicht wollen, um eine "Frage" unbeantwortet, und nicht wollen, um eine "Antwort" auf das Finale eine, die "Antworten" auf die Frage " wünschen Sie, dass es einige-Modus hier, um Vorschläge für Projekte, die wir machen...
  • Ich Frage mich, warum sind wir rotierenden bitmap in der java-Welt verursachen OOM (überschreiten heap space?) aber in JNI ist es das nicht ? Dank
  • Das ist, weil in der Java Welt haben Sie einen Haufen, die begrenzt ist durch eine viel kleinere Menge an RAM, um die trigger-OOM. Zum Beispiel, angenommen, Ihr Gerät hat 4GB RAM, aber jede app hat einen Haufen von 64 MB. Es bedeutet, dass durch die Verwendung von Java allein, Ihre Speichernutzung kann nicht gehen über die 64 MB Grenze, und wenn man es versucht, wird es Abstürzen, weil es. Bei der Verwendung von JNI, der tatsächliche RAM von dem Gerät, so hat es viel weniger chance, mit Speicher-Beschränkung Probleme.

Schreibe einen Kommentar