[android] JNI, чтобы помочь избежать OOM при использовании больших изображений



Answers

Question

задний план

в большинстве случаев получение OOM на android связано с использованием слишком большого количества растровых изображений и / или создания больших растровых изображений.

недавно я решил попробовать JNI, чтобы избежать использования OOM, сохранив данные непосредственно на стороне JNI.

после беспорядка с JNI на некоторое время, я создал несколько сообщений в SO, просящих о помощи и поделиться своими знаниями, и теперь я решил поделиться с вами еще одним кодом. вот должности, если кто-то заинтересован в чтении результатов или содействии:

  • Как кэшировать растровые изображения в встроенную память

  • декодирование изображений и манипуляции с использованием JNI на Android

  • JNI - как использовать несколько экземпляров оболочки Jni с разными полями?

  • Поворот растрового изображения с использованием JNI & NDK

на этот раз я добавил возможность сохранять, восстанавливать, обрезать и поворачивать растровые изображения. это должно быть легко добавить дополнительные параметры, и я был бы рад, если бы другие люди добавили свой собственный код в более полезные функции .

поэтому код, который я собираюсь показать, на самом деле объединяет все, что я создал.

образец кода использования:

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

Проект доступен на github

  • Страница проекта доступна на сайте github.

  • не стесняйтесь давать советы и вносить свой вклад.

важные заметки

такие же заметки, как показано здесь , плюс:

  • текущие функции, которые написаны здесь (более подробно на странице проекта):

    • магазин

    • восстановить

    • вращаться на 90 градусов против часовой стрелки

    • растениеводство.

  • подход, который я использовал для этого кода, - это как эффективность памяти (используйте только память, которая мне нужна, и освободите ее, когда это не нужно), и эффективность процессора (я старался использовать оптимизацию кэшей указателей и ЦП, когда это возможно).

  • для лучшей производительности я сделал действительно несколько валидаций, особенно в части JNI. лучше всего было бы управлять валидациями в Java-мире.

  • есть еще много недостающих функций, которые, я думаю, нужно добавить, и я надеюсь, что у меня будет время их добавить. если кто-то хочет внести свой вклад, я буду рад добавить их код тоже. вот функции, которые, по моему мнению, могут быть полезны:

    • получить текущую растровую информацию

    • масштабные растровые изображения, в том числе выбор того, какой алгоритм использовать (ближайший сосед и билинейная интерполяция должны быть достаточными).

    • использовать разные форматы растровых изображений

    • выполните декодирование внутри JNI, чтобы избежать создания java-растрового изображения (и не использовать кучу в мире java) с самого начала, только в конце, когда вы закончили все операции.

    • обнаружение лица

    • вращение под любым углом или, по крайней мере, очевидные. в настоящее время я только добавил поворот на 90 градусов против часовой стрелки.




Links