Масштабированные изображения с залпом
Я пытаюсь растянуть изображения, которые я загружаю залпом. XML не очень помогает, хотя он может уменьшить их, но не поможет расширить их. Изучение этой темы привело меня к выводу, что это может быть достигнуто только программно.
В чем моя идея?
Расширить библиотеку залпов и переопределить один из методов, изменив размер растрового изображения сразу после загрузки и перед его отображением.
Я использовал этот код для изменения размера изображений, которые уже были на телефоне, но это не очень помогает со случайными изображениями из Интернета.
Point outSize=new Point();
float destWidth=1;
float destHeight=1;
@SuppressWarnings("deprecation")
@TargetApi(13)
private Bitmap scaleBitmap(int mFile){
Display display = getActivity().getWindowManager().getDefaultDisplay();
if (android.os.Build.VERSION.SDK_INT >= 13){
display.getSize(outSize);
destWidth = outSize.x;
destHeight = outSize.y;
}else{
destWidth=display.getWidth();
destWidth=display.getHeight();
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap orig = BitmapFactory.decodeResource(getResources(), mFile);
float srcWidth = orig.getWidth();
float srcHeight = orig.getHeight();
float inSampleSize = 1;
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
inSampleSize=(destHeight/2)/srcHeight;
}else{
inSampleSize=(destHeight/4)/srcHeight;}
options = new BitmapFactory.Options();
Bitmap resized=Bitmap.createScaledBitmap(orig, (int)Math.round(orig.getWidth()*inSampleSize), (int)Math.round(orig.getHeight()*inSampleSize), true);
destWidth=1;
destHeight=1;
return resized;
}
По сути, я хочу присвоить orig-образу загруженное изображение, а затем изменить его размер и отобразить. Мой вопрос: какой класс мне продлить? Я посмотрел туда, но так как я неопытный, я не мог понять, что именно искать. Это ImageLoader? И более конкретно: должен ли я переопределить метод getBitmap() и добавить отредактированную версию кода для масштабирования?
Отказ от ответственности: я очень неопытный, и я бы принял другие идеи.
2 ответа
Я решил это несколько дней назад. Вот как обычный ImageView обрабатывает изменение размера изображений: если вы используете Match_parent в качестве ширины и wrap_content в качестве высоты (я проверял оба значения в качестве match_parent, и результаты были одинаковыми), он НЕ будет масштабировать изображение, ЕСЛИ высота вашего изображения ниже чем ширина (что довольно типично) . Это означает, что представление изображения масштабируется в зависимости от меньшей стороны. Это означало, что есть 2 решения:
- Сделайте то, что я хотел сделать изначально, что включает в себя написание нового класса, который расширяет imageview/networkimageview, а затем программно добавьте код, который я перечислил, чтобы увеличить изображение.
- Или просто укажите желаемую высоту вида программно, и изображение затем просто масштабирует изображение, чтобы соответствовать высоте нового вида. Эта опция делает недействительным wrap_content для Width и просто добавляет столько, сколько вам нужно.
Вот код, который я использовал:
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point outSize=new Point();
int destWidth;
if (android.os.Build.VERSION.SDK_INT >= 13){
display.getSize(outSize);
destWidth = outSize.x;
}else{
destWidth=display.getWidth();
}
img.setLayoutParams(new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT,destWidth*5625/10000));
В моем случае мне нужно было уместить изображение размером 640x360, поэтому я использовал соотношение 0,5625. Этот метод будет работать, если вы не знаете параметров изображения, НО вам нужно заранее получить параметры и поставить их на место, поэтому я думаю, что было бы более полезно использовать первую стратегию, но, поскольку я решил свою проблему, я не есть пример для первого метода.
Я думаю, что проблема, которую вы видите, вызвана поведением по умолчанию того, как работает базовый код для NetworkImageView.
Взгляните на код для ImageRequest, который используется NetworkImageView. Там есть функция с именем getResizedDimension, которая говорит что-то вроде "Масштабирует одну сторону прямоугольника, чтобы соответствовать пропорциям". Возможно, это вызвало вашу проблему, поскольку загружаемые изображения (изображения) могут не иметь идеального соотношения сторон, вычисляемого каждый раз для конкретного устройства.
Отображаете ли вы одно изображение или изображения в сетке? Если это всего лишь одно изображение, возможно, существует обходной путь. Я не видел ваш полный код, где вы устанавливаете изображение или URL-адрес изображения, поэтому я собираюсь принять поток здесь:
1.) Используйте обычный ImageView.
2.) Используйте обычный запрос Volley, указывающий на URL изображения
3.) Когда вы получите ответ (parseNetworkResponse), декодируйте его (массив байтов) самостоятельно, используя метод, который вы упомянули выше, который работает для вас. Здесь также можно найти несколько советов о том, как это сделать: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
4.) После декодирования программно установите растровое изображение ImageView с вашим декодированным результатом.
Если это тип сетки, то, возможно, вам нужно создать собственную версию NetworkImageView и его базовых классов поддержки (подкласс).
Предложение:
Посмотрите и на Пикассо, если у вас есть свобода выбора библиотеки. Выглядит очень просто в использовании для ваших заявленных потребностей.