2011-01-28 3 views
20

Благодаря Schermvlieger для спрашивать this вопрос о anddev.org,Оптимальное использование BitmapFactory.Options.inSampleSize скорости

Я просто копируют его вопрос не так, как никто ответил на другой сайт, и я также сталкиваюсь с той же проблемой.

Мне было интересно, что было бы оптимальным использованием BitmapFactory.Options.inSampleSize относительно скорости отображения изображения.
В документации упоминается с использованием значений, которые являются степенью 2, поэтому я работаю с 2, 4, 8, 16 и т.д.

То, что я задаюсь вопросом о том, являются:

  1. Должен ли я ресэмплировать вниз до самого маленького размера, который по-прежнему больше разрешения экрана, или я должен делать выборку до размера, достаточного для того, чтобы избежать OutOfMemoryError?
  2. Как вычислить максимальный размер изображения, которое все еще может отображаться без исчерпания памяти? Идет ли цветная глубина изображения, а также глубина дисплея?
  3. Эффективно отображать изображения с помощью двух механизмов (BitmapFactory для больших файлов, setImageURI() для небольших). Я использую ImageSwitcher.
  4. Помогло ли это создать Bitmap, BitmapFactory.Options и inTempStorage в начале приложения или создать их только на лету, при необходимости?

ответ

11

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

Учитывая стоимость памяти изображения, да, цветовая депция играет очень важную роль. Изображения в формате ALPHA_8 используют 1 байт на пиксель, изображения в RGB_565 или ARGB_4444 используют 2 байта на пиксель, а изображения в ARGB_8888 используют 4 байта на пиксель. Глубина отображения не имеет значения. Вы всегда должны пытаться использовать ARGB_8888 для получения наилучшего качества, но 565 может быть достаточно хорошим, если ваше изображение непрозрачно.

+0

Когда вы говорите, что «масштабирование изображений во время рисования чрезвычайно дорого», это включает в себя options.inSampleSize? – kape123

+0

inSampleSize используется для масштабирования изображений во время загрузки, а не во время рисования. Это очень хороший способ предварительного масштабирования изображений. –

+1

Мы используем ARGB_8888, который производит очень туманное изображение на Samsung Galaxy Note 2, но он хорошо работал на другом устройстве, принеся его на ARGB_4444, сбой приложения на Samsung Galaxy Note 2 и Pad 3110 из-за outOfMemoryError. Не могли бы вы помочь нам разобраться в этом. –

3

Здесь вы можете позвонить определенному пользователем методу shrinkmehtod, который фактически отправит путь к файловому файлу, а также высоту и ширину, чтобы уменьшить изображение до метода.

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

Это пользовательский метод, позволяющий программно уменьшить размер изображения.

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

Я надеюсь, что это поможет вам уменьшить размер.

+2

Отправлено отсюда http://madhusudhanrc.blogspot.fr/2012/09/reduce-bitmap-size-using.html – Snicolas

4

Вы задали хорошие вопросы, но все зависит от ваших потребностей и того, сколько памяти вы используете. Я рекомендую проверить эту ссылку для многих советов относительно растровых изображений: http://developer.android.com/training/displaying-bitmaps/index.html.

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

Вот мои ответы на ваши вопросы:

  1. Почему не так? если вы думаете, что может быть OOM, попробуйте переработать старые, неиспользуемые растровые изображения, а затем снова проверьте.

  2. можно вычислить (оценка) размер битовой карты:

    ширина * высота * bytesPerPixel

    , где bytesPerPixel, как правило, 4 или 2 (в зависимости от формата растрового).

  3. Никогда не использовал setImageURI, поэтому я не могу с этим поделать. Я предлагаю загружать изображения в фоновый поток (используя asyncTask - это один из способов сделать это) и показывать их, когда он будет готов.

  4. Если есть только несколько, которые вы знаете, что не займет много памяти, я думаю, все в порядке. Я все еще думаю, что кэширование может быть лучше.

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