Подтвердить что ты не робот

Оптимальное использование BitmapFactory.Options.inSampleSize для скорости

Благодаря Schermvlieger для запроса этого вопроса anddev.org,

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

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

То, что мне интересно, это:

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

Ответ 1

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

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

Ответ 2

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

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

Здесь мои ответы на ваши вопросы:

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

  • вы можете вычислить (оцененный) размер растрового изображения:

    width * height * bytesPerPixel

    где bytesPerPixel обычно 4 или 2 (в зависимости от формата растрового изображения).

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

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

Ответ 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;

    }

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