#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
Комментариев нет:
Отправить комментарий