Страницы

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

пятница, 24 января 2020 г.

Как лучше хранить картинки приложения в drawable или assets

#java #android #bitmap #android_drawable #android_assets


Приложение имеет сложный дизайн и по этому было решено делать прорисовку на surfaceView,
то есть почти нет никаких xml файлов, все отрисовывается программно.  Но есть достаточно
большое кол-во небольших png файлов, разного размера. Подскажите каким образом лучше
хранить все эти файлы? варианты которые я рассматриваю: drawable - хранить в общей
папке и изменять их размер программно, assets - все то же самое и есть третий вариант
- загружать все картинки как атлас текстур в одном файле а потом создавать bitmap'ы
по областям большого файла.
Опишите пожалуйста плюсы и минусы каждого варианта, может есть ещё какие-то варианты
с которыми вы сталкивались?(Загрузка через интернет не подходит).
    


Ответы

Ответ 1



Каталог asset принципиально отличается от drawable тем, что drawable позволяет хранить разные картинки для разных разрешений, ориентаций и локалей. asset же позволяет организовать хранение в виде как бы файлов. Для вашего случая, я полагаю, drawable таки более предпочителен, поскольку вы можете организовать доступ через идентификаторы картинок, в случае же asset вам придется организовать доступ через как бы файловую систему, с чтением, организацией потока и проч., типа так: public void loadImageFromAsset() { try { InputStream ims = getAssets().open("cat.jpg"); Drawable d = Drawable.createFromStream(ims, null); mImage.setImageDrawable(d); } catch(IOException ex) { return; } } Теперь, вопрос касательно "пилить/не пилить" на картинки для разных dpi, принципиально это отличается только тем что в случае если вы не будете "пилить" картинки, то вы или накалываетесь на OutOfMemoryException на больших картинках, либо программно меняете разрешение картинки через InSampleSize (масштабирование картинки): public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; } То есть выводите так: // сначала проверяете реальный размер битмапа final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); //далее вычисляем inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // теперь декодируем с правильным масштабированием options.inJustDecodeBounds = false; Bitmap bimtap=BitmapFactory.decodeResource(res, resId, options); //отображаем imageView.setImageBitmap(bitmap); Подробнее здесь Так вот в случае, когда картинки хранятся в раздельных drawable-??dpi - все эти вычисления делаются уже заранее. Тем самым экономится время на масштабирование картинок. Вам решать, хотите вы заранее масштабировать или вы согласны часть процессорного времени убить на вычисления с масштабированием - зависит от задачи. Если решите не "пилить" картинки на разные dpi - складывайте их в drawable-nodpi. По-поводу кэширования или асинхронной загрузки картинок. Существует довольно много различных либ, которые решают эту проблему, например universal-image-loader или новомодный Picasso

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

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