2016-08-26 3 views
2

Существует так много материалов по плотности, multiple screen support, так много questions on SO, но у меня все еще нет.Масштабирование ресурсов изображения в Android и Picasso

Моя цель проста: отобразить растровое изображение размером с доступное пространство для ImageView. Мне нужно BitMap, поскольку я буду выполнять некоторые операции над ним.

<ImageView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/figureView" /> 

У меня будет несколько изображений, которые будут использоваться в растровом изображении. Я разместил их в каталоге drawables. Я буду ссылаться на них с R.drawable.pictureX. Я буду использовать Пикассо, чтобы загрузить их и масштабировать их:

Bitmap bitmap = Picasso.with(getContext()).load(resourceId).resize(w, h).get(); 

Неясная часть для меня все эти xxhdpi папки и Android эвристики, чтобы выбрать лучший.

  1. Когда в документации говорится, что Android будет автоматически масштабировать изображение, это применимо к моему делу? Я не хочу масштабировать масштабные фотографии.

  2. Сколько вариантов dpi можно сохранить в моем случае и где? Должен ли я иметь один файл в папке с не-dpi или я должен создать вариант изображения для каждой папки с тэпом?

  3. Как определить размер для ресурса изображения? Это легко для значков: например, 24x24 dpi, а затем несколько с формулой DPI. Но я хочу покрыть полную высоту экрана. Глава Примеры конфигурации списки: 240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 720x1280 mdpi, 800x1280 mdpi и т. Д. Для ресурсов нет спецификаторов размера экрана.

Спасибо за разъяснения.

ответ

1

1. Андроид автоматически масштабирует изображение в случае, если вы предоставили изображение для одного экрана и нет такого изображения для другого. например если вы добавите свое изображение только в папку drawable-xxxhdpi, Android будет генерировать изображения для xxhdpi, xhdpi-экранов и т. д.

2. Вы можете сохранить свое изображение в одной папке drawable-xxxhdpi и позволить Android сделать downscale, если вы не нравится результат, вы можете создавать изображения для разных ресурсов по своему усмотрению.

name dencity scale 
mdpi 160dpi x1 
hdpi 240dpi x1.5 
xhdpi 320dpi x2 
xxhdpi 480dpi x3 
xxxhdpi 640dpi x4 

3.Вы можете определить размеры ваших изображений в зависимости от размера изображения и масштаба изображения. Например, если ваш ImageView имеет ширину 80dp и высоту 40dp, тогда ваше изображение для папки drawable-mdpi должно иметь размер 80x40px, потому что mdpi - это базовая плотность, для drawable-hdpi тогда вам нужно иметь изображение 120x60px (масштаб 1,5) и т. Д. Для drawable-xxxhdpi ваше изображение будет 320x160px.

Если вы хотите, чтобы ваше изображение соответствовало всем экранам на всех устройствах, вы можете использовать параметр android:scaleType="centerCrop", он заставит изображение занять все пространство, но небольшая часть изображения может быть скрыта в зависимости от соотношения сторон экрана. Вы также можете попытаться указать результирующие изображения на основе кратчайшего размера доступной области экрана, например. drawable-sw720dp. Узнайте больше об этом here.

+0

Спасибо за ваш ответ. Действительно ли Android действительно масштабирует картинку? Я думаю, что Пикассо мог использовать BitmapFactory.Options.inScaled, чтобы избежать этого. Я надеюсь, что он может выбрать лучший ресурс соответствия. Я буду создавать несколько разных вариантов, чтобы проверить это. –

+0

Если вы не хотите, чтобы ваше изображение масштабировалось, вы можете поместить его в папку 'drawable-nodpi'. Но удостоверьтесь, что у вас нет такого изображения у других выносных кормушек, потому что если вы сделаете, то изображение будет взято из другого ресурса. – dzikovskyy

2

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

Существует sample GitHub Test DPI project. Он имеет два ImageView с. Первый инициализируется из XML и Android делает масштабирование. Второй - это заполнитель, который я заполняю BitMap. Я ввел 200dp как его размер, и это было правильно. Размер пикселя MDPI = размер в dp.

enter image description here

То, что я нашел это логично. Android ничего не знает о моих намерениях. Он просто выбирает лучший доступный ресурс для текущего DPI.

Nexus 5x использует XXHDPI по умолчанию, Samsung SIII Mini использует HDPI. Если я удалю свои папки DPI по умолчанию, они уменьшат более высокий доступный вариант: XXXHDPI и XHDPI. Если я удалю все варианты, кроме NODPI, это будет использоваться.

И, наконец, если я изменю размеры динамического изображения ImageView с исходного кода на 300dp, тогда он будет масштабироваться и выглядеть уродливым. Android не может знать при исполнении decodeResource, что я буду масштабировать его позже и что есть лучший доступный ресурс.

Что остается неизвестным, так это узнать размеры изображения, которое соответствует экрану.

Java:

BitmapFactory.Options opt = new BitmapFactory.Options(); 
opt.inScaled = false; 
Bitmap figureBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_test, opt); 
ImageView imageView=(ImageView) findViewById(R.id.testView); 
imageView.setImageBitmap(figureBitmap); 

активность:

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_test" /> 
<ImageView 
    android:id="@+id/testView" 
    android:layout_width="200dp" 
    android:layout_height="200dp" /> 

Update 30 августа

Оригинал фотографии: 230x541 точек, загрузка с

Picasso.with(getContext()).load(R.drawable.amalka).into(target) 
  1. хранится в nodpi, погрузили в 230x541 рх Bitmap
  2. хранится в xxhdpi, погрузили в 230x541 рх Bitmap
Смежные вопросы