Масштабированные изображения с залпом

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

Какова моя идея?

Для расширения библиотеки volley и переопределения одного из методов изменения размера растрового изображения сразу после загрузки и перед его отображением.

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

        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;
        }

В основном я хочу назначить исходное загруженное изображение, затем изменить его размер и затем отобразить. Мой вопрос: какой класс я расширяю? Я посмотрел там, но, поскольку я неопытен, я не мог понять, что именно искать. Это ImageLoader? А точнее: следует ли переопределить метод getBitmap() и добавить отредактированную версию кода для масштабирования?

Отказ от ответственности: я очень неопытен, и я бы принял и другие идеи.


person user3542472    schedule 11.11.2014    source источник
comment
Вы используете NetworkImageView? Он должен сделать масштабирование для вас.   -  person zgc7009    schedule 12.11.2014
comment
Да. Пробовал использовать параметр linearlayout androdi_weight, но картина осталась прежней. Однако вид становится больше (это означает, что фоновое изображение растягивается, чтобы соответствовать). Как я уже сказал, изображение становится меньше, если я уменьшаю вес, но после достижения исходного размера оно останавливается. Вот где я хочу добавить изменение размера.   -  person user3542472    schedule 12.11.2014
comment
Вам нужно изменить scaleType вашего NetworkImageView. Попробуйте android:scaleType=fitCenter   -  person zgc7009    schedule 12.11.2014
comment
Я пробовал все 8 вариантов scaleType, и ни один из них не делает то, что мне нужно. Мне нужно, чтобы изображение соответствовало ширине_parent и занимало столько места, сколько нужно по высоте (обертка_содержимого). Но ни одна из опций в scaleType этого не делает. Они либо не совпадают с ним внутри родителя, либо искажают или обрезают изображение. Для layout_width и height я использую match/wrap соответственно.   -  person user3542472    schedule 12.11.2014
comment
Он хорошо вписывается в X, но искажает его в Y. Он не сохраняет то же соотношение.   -  person user3542472    schedule 12.11.2014
comment
Я думаю, что могу запутаться и не сильно помочь. Если у вас есть NetworkImageView с width:wrap_content и height:match_parent с scaleType:centerInside, вы должны делать то, что хотите. он будет обертывать содержимое ширины, равномерно масштабировать изображение и следить за тем, чтобы высота или ширина соответствовали полностью. Если вы хотите масштабировать его, чтобы убедиться, что ширина соответствует, что произойдет, если ваше изображение выше, чем в ширину? Он будет растягиваться за пределы поля зрения или искажаться. Это то, что вы хотите?   -  person zgc7009    schedule 12.11.2014
comment
Мне нужна ширина:match_parent и высота:wrap_content. Когда я использую centerInside, он ничего не делает, только изображение с исходным разрешением. Если я использую centerCrop, он масштабируется по X и Y, но обрезает части изображения по Y. Я понятия не имею, почему это так, поскольку весь макет основан на обертке по высоте.   -  person user3542472    schedule 12.11.2014


Ответы (2)


Я решил это несколько дней назад. Вот как обычный ImageView обрабатывает изменение размера изображений: если вы используете Match_parent в качестве ширины и wrap_content в качестве высоты (я тестировал оба как match_parent, и результаты были одинаковыми), он НЕ будет масштабировать изображение, ЕСЛИ высота вашего изображения ниже чем ширина (что вполне типично). Это означает, что масштаб изображения зависит от меньшей стороны. Это означало, что есть 2 решения:

  • Сделайте то, что я хотел сделать изначально, что включает в себя написание нового класса, расширяющего imageview/networkimageview, а затем программным добавлением кода, который я перечислил, чтобы увеличить изображение.
  • Или просто укажите желаемую высоту представления программно, и затем изображение просто масштабирует изображение, чтобы оно соответствовало высоте нового представления. Эта опция аннулирует wrap_content для ширины и просто вставляет столько, сколько вам нужно.

Вот код, который я использовал:

 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. Этот метод будет работать, если вы не знаете параметры изображения, НО вам нужно заранее получить параметры и поставить их на место, поэтому я думаю, что может быть полезнее использовать первую стратегию, но так как я решил свою проблему, я не есть пример для первого метода.

person user3542472    schedule 26.11.2014

Я думаю, проблема, которую вы видите, вызвана поведением по умолчанию того, как работает базовый код для 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 и его базовые классы поддержки (подкласс).

Предложение:

Взгляните также на Picasso, ЕСЛИ у вас есть свобода выбора библиотеки. Выглядит очень просто в использовании для ваших заявленных потребностей.

person alpinescrambler    schedule 11.11.2014