Измените размер изображения на полную ширину и фиксированную высоту с помощью Picasso

У меня есть вертикальная LinearLayout, где один из элементов является ImageView загружен с помощью Picasso. Мне нужно увеличить ширину изображения до полной ширины устройства и отобразить центральную часть изображения, обрезанную на фиксированную высоту (150 точек на дюйм). В настоящее время у меня есть следующий код:

Picasso.with(getActivity()) 
    .load(imageUrl) 
    .placeholder(R.drawable.placeholder) 
    .error(R.drawable.error) 
    .resize(screenWidth, imageHeight)
    .centerInside() 
    .into(imageView);

Какие ценности я должен положить в screenWidth а также imageHeight (=150dp)?

3 ответа

Решение

Ты ищешь:

.fit().centerCrop()

Что это значит:

  • fit - подожди, пока ImageView было измерено и изменить размер изображения, чтобы точно соответствовать его размеру.
  • centerCrop - масштабируйте изображение в соответствии с соотношением сторон, пока оно не заполнит размер. Обрежьте верхнюю и нижнюю часть или левую и правую, чтобы он точно соответствовал размеру.

В этом блоге подробно описываются функции изменения размера и подгонки Пикассо: https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit.

Изменение размера изображения с помощью resize(x, y)

Как правило, оптимально, если ваш сервер или API доставляют изображение в нужных вам размерах, что является идеальным компромиссом между пропускной способностью, потреблением памяти и качеством изображения.

К сожалению, вы не всегда можете запросить изображения в идеальных размерах. Если изображения имеют странный размер, вы можете использовать вызов resize(horizontalSize, verticalSize), чтобы изменить размеры вашего изображения на более подходящий размер. Это изменит размер изображения перед его отображением в ImageView.

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .resize(600, 200) // resizes the image to these dimensions (in pixel). does not respect aspect ratio
    .into(imageViewResize);

Использование scaleDown()

При использовании опции resize() Picasso также увеличит изображение. Поскольку увеличение размера небольшого изображения без улучшения качества изображения может привести к потере вычислительного времени, вызовите scaleDown(true), чтобы применять функцию resize() только в том случае, если исходное изображение имеет большие размеры, чем целевой размер.

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .resize(6000, 2000)
    .onlyScaleDown() // the image will only be resized if it's bigger than 6000x2000 pixels.
    .into(imageViewResizeScaleDown);

Избегание растянутых изображений с масштабированием

Теперь, как и при любой манипуляции с изображением, изменение размера изображения может реально исказить соотношение сторон и ухудшить отображение изображения. В большинстве случаев вы хотите предотвратить это. Пикассо дает вам два варианта смягчения: call centerCrop() или centerInside ().

CenterCrop

CenterCrop () - это метод обрезки, который масштабирует изображение так, чтобы оно заполняло запрошенные границы ImageView, а затем обрезал лишнее. ImageView будет заполнен полностью, но все изображение может не отображаться.

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .resize(600, 200) // resizes the image to these dimensions (in pixel)
    .centerCrop() 
    .into(imageViewResizeCenterCrop);

CenterInside

CenterInside () - это метод обрезки, который масштабирует изображение таким образом, чтобы оба измерения были равны или меньше запрошенных границ ImageView. Изображение будет отображаться полностью, но может не заполнять весь ImageView.

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .resize(600, 200)
    .centerInside() 
    .into(imageViewResizeCenterInside);

И последнее, но не менее важное: Fit Picasso (). Обсуждаемые параметры должны охватывать ваши потребности в функциональности, касающейся изменения размера и масштабирования изображения. Есть одна последняя вспомогательная функциональность Picasso, которая может быть очень полезна: fit().

Picasso  
    .with(context)
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .fit()
    // call .centerInside() or .centerCrop() to avoid a stretched image
    .into(imageViewFit);

fit () измеряет размеры целевого ImageView и внутренне использует resize(), чтобы уменьшить размер изображения до размеров ImageView. Есть две вещи, которые нужно знать о fit(). Во-первых, вызов fit () может задержать запрос изображения, поскольку Picasso нужно будет подождать, пока размер ImageView не будет измерен. Во-вторых, вы можете использовать только fit () с ImageView в качестве цели (мы рассмотрим другие цели позже).

Преимущество состоит в том, что изображение имеет минимально возможное разрешение, не влияя на его качество. Более низкое разрешение означает меньше данных, которые будут храниться в кэше. Это может значительно уменьшить влияние изображений на объем памяти вашего приложения. Таким образом, если вы предпочитаете меньшее влияние на память по сравнению с немного более быстрым временем загрузки, то fit () - отличный инструмент.

В некоторых случаях функция fit() бесполезна. Прежде чем ждать окончания измерения ширины и высоты. Таким образом, вы можете использовать globallayoutlistener. например;

imageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                Picasso.with(getActivity())
                        .load(imageUrl)
                        .placeholder(R.drawable.placeholder)
                        .error(R.drawable.error)
                        .resize(screenWidth, imageHeight)
                        .fit
                        .centerInside()
                        .into(imageView);
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });
Другие вопросы по тегам