2014-01-15 2 views
1

BitmapFactory.decodeFile вызывает outOfMemoryError только тогда, когда я выбираю изображение из галереи телефона, а не тогда, когда я выбираю изображение для съемки фотографии с намерением камеры. Я фактически избегаю использования decodeFile при использовании намерения камеры. Могу ли я использовать тот же подход при выборе из галереи (получение данных из намерения)? Вот мой код для получения изображения в обоих направлениях:BitmapFactory.decodeFile вызывает outOfMemoryError

Если изображение было выбрано из устройства»Галерея:

if (requestCode == 1) 
       { 
        if (intent != null && resultcode == RESULT_OK) 
        { 
        ImageHelper ih = new ImageHelper(); 
        mProfilePicPath = ih.getSelectedImageFilePathFromGallery(this, intent); 
        Bitmap portraitPhoto = ih.getChosenImageFromGallery(mProfilePicPath); 
        try{ 
         ih.saveImage("Profile pics", portraitPhoto, this); 

ImageHelper.getChosenImageFromGallery:

public Bitmap getChosenImageFromGallery(String imagePath) { 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(imagePath, options); 
     options.inSampleSize = DressingRoomActivity.calculateInSampleSize(options, 500, 500); 
     options.inJustDecodeBounds = false; 
     Bitmap portraitPhoto = ImageHelper.convertToPortraitOrientation(options, imagePath); 
     return portraitPhoto; 
    } 

Если изображение было выбрано с фото с использованием камеры:

else if ((requestCode == CAMERA_REQUEST)&& (resultcode == Activity.RESULT_OK)){ 
       Bundle extras = intent.getExtras(); 
       Uri selectedImage = intent.getData(); 
       if (extras != null) { 
        ImageHelper ih = new ImageHelper(); 
        mProfilePicPath = ih.getFilePathFromCameraPhoto(this, selectedImage); 
        Bitmap photo = (Bitmap) intent.getExtras().get("data"); 
        try{ 
        ih.saveImage("Profile pics", photo, this); 

Как вы можете видеть, чтобы захватить изображение из галле ry и получить Bitmap от него, мне нужно создать битмап только 500 х 500 пикселей с помощью этого кода options.inSampleSize = DressingRoomActivity.calculateInSampleSize(options, 500, 500); В противном случае он вызывает outOfMemoryError в строке Bitmap bmp = BitmapFactory.decodeFile(path, options); Что находится в методе ImageHelper.convertToPortraitOrientation(options, imagePath);. Это означает, что пользователь получает качество AS IS в своем изображении с камеры и качество 500 пикселей от их изображения в галерее.

Мои вопросы: 1) Есть ли способ не сделать мое качество изображения 500 пикселей при выборе из галереи? Как избежать этой строки как-то: Bitmap bmp = BitmapFactory.decodeFile(path, options); или каким-то другим способом?

2) С галереей мне пришлось преобразовать в портрет, который является лишь незначительным раздражением, но почему это так? Он меняет фотографию сбоку, если я этого не делаю.

ответ

0

Существует 2 возможных пути решения проблем OutOfMemory исключение:

Решение 1: Вы должны использовать WeakReference переменные, как.

WeakReference<Bitmap> weakReferenceBitmap=new 
      WeakReference<Bitmap>(bitmap); 

GC clear weakReference variable более эффективен по сравнению с другими.

Решение2: вы можете использовать свойство largeHeap в своем манифесте, чтобы потребовалось больше места для кучи, чем обычно.

<application 
     android:largeHeap="true"> 

</application> 

Я не буду рекомендовать вам 2-ое решение, но это работает :)

Надеется, что это поможет :)

+0

Спасибо! BigHeap звучит так, как будто он не может использоваться на устройствах низкого качества для Android.Будет ли WeakReference работать в этом методе, если я его отредактирую? 'public static Bitmap createRotatedBitmap (битмап bm, степень плавания) { \t Bitmap bitmap = null; \t if (degree! = 0) { \t Матричная матрица = новая матрица(); \t matrix.preRotate (degree); \t bitmap = Bitmap.createBitmap (bm, 0, 0, bm.getWidth(), \t bm.getHeight(), matrix, true); \t} \t return bitmap; \t} ' – user3164083

+0

WeakRefrence будет работать! Но если вы делаете слишком много декодирования, вы должны использовать опцию largeHeap. Не беспокойтесь, приложение будет работать и на устройствах с низким качеством Android. –

+0

Спасибо :) Это приложение - все об изображениях. Существует много расшифровки. Поэтому я буду использовать largeHeap. Должен ли я использовать WealReference , на ваш взгляд? – user3164083

1

Here полный Tuto о том, как Display Bitmaps Efficiently из официального дока. У меня была такая же проблема, как и вы. То, что я сделал, - это прочитать и понять все уроки с данной страницы, прежде чем вернуться к моим кодам. Попытайтесь это, вы поймете, что у вас все в порядке.

Редактировать

Ваше приложение рушится, потому что вы работаете метод Bitmap.decode() в главном потоке. Используйте другой поток (с простым AsyncTask), чтобы сделать это.

Как я уже говорил, есть a nice tuto on how to handle bitmap off UI Thread

+0

Да, я согласен, я думаю, мне нужно это прочитать. Благодаря! – user3164083

+0

После прочтения этого, я думаю, что большинство этих подходов относятся к производительности. На данный момент я просто смотрю на то, чтобы не сбивать память. Я думаю, что единственное исправление заключалось в том, что изображение было меньше, чем я уже делаю:/Он сказал, что Кэширование может использовать больше памяти. Он также предложил не использовать WeakReference. Не совсем уверен, что делать, поскольку мне нужен выходной образ того же качества, что и вход. Это приложение для редактирования фотографий. – user3164083

+0

см. Мое редактирование. «Я просто смотрю на то, что на данный момент не сбой памяти»: вам нужно хорошо обрабатывать растровые изображения, чтобы избежать сбоя приложения. Вот почему я предоставил ссылку выше. Прочтите тутологи, попытайтесь понять и вернуться на любой вопрос. –

Смежные вопросы