Страницы

Поиск по вопросам

понедельник, 18 марта 2019 г.

Как избавиться от ООМ при работе с Bitmap?

Я работаю с Bitmap и рабочий процесс выглядит так
Юзер делает фото, оно сохраняется в файл после чего открывается юзеру для подтверждения. Если юзер подтверждает фото то выполняется crop части фото и еще раз показывается юзеру для подтверждения.
Таким образом юзер делает 5 фото.
Так вот после первой фото и все хорошо. Фото показывается юзеру и проходит 2 этапа подтверждения.
Но на втором фото юзеру показывается фото , он ее подтверждает и получает ошибку
FATAL EXCEPTION: AsyncTask #2 Process: com.fittingroom.newtimezone, PID: 7196 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:309) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.OutOfMemoryError: Failed to allocate a 63489036 byte allocation with 16777216 free bytes and 60MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:882) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:858) at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:478) at com.fittingroom.newtimezone.presenters.PresenterActivityAcceptNotAccept.getCroppedBitmapFromPath(PresenterActivityAcceptNotAccept.java:65) at com.fittingroom.newtimezone.presenters.PresenterActivityAcceptNotAccept.access$200(PresenterActivityAcceptNotAccept.java:16) at com.fittingroom.newtimezone.presenters.PresenterActivityAcceptNotAccept$1.doInBackground(PresenterActivityAcceptNotAccept.java:41) at com.fittingroom.newtimezone.presenters.PresenterActivityAcceptNotAccept$1.doInBackground(PresenterActivityAcceptNotAccept.java:31) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  at java.lang.Thread.run(Thread.java:818)
вот код в котором появляется ошибка
private Bitmap getCroppedBitmapFromPath(String path) { final File photo = new File(path); final BitmapFactory.Options options = new BitmapFactory.Options(); final Bitmap bitmap = BitmapFactory.decodeFile(photo.getAbsolutePath(), options); int height = bitmap.getHeight();
Bitmap result; final Matrix matrix = new Matrix(); matrix.postRotate(90); final double centerX = height * 0.5; final double centerY = height / 447 * 480; final double widthAndHeight = height / 447 * 160; final int pointY = (int) (centerX - widthAndHeight / 2); final int pointX = (int) (bitmap.getWidth() - centerY - widthAndHeight / 2); final int widthAndHeightResult = (int) widthAndHeight; result = Bitmap.createBitmap(bitmap, pointX, pointY, widthAndHeightResult, widthAndHeightResult, matrix, false);
return result; }
Вот в этой строчке
final Bitmap bitmap = BitmapFactory.decodeFile(photo.getAbsolutePath(), options);
может как то нужно освобождать байты с которыми Bitmap работает?
или может как то уменьшить размер картинки?


Ответ

Можно, если это например jpeg или png работать с картинкой меньшего качества, а потом уже приводить ее к нормально виду, когда закончили работу.
А как менять качество:
BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; final Bitmap bitmap = BitmapFactory.decodeFile(selectedImageUri.getPath(), options);
Да и в плюс данного метода:
наверняка эта картинка маленькая, результирующая нет смысла показывать хорошее качество

Комментариев нет:

Отправить комментарий