programing

이미지 보기 너비를 채우고 가로 세로 비율을 유지하도록 이미지 배율 조정

topblog 2023. 8. 1. 20:13
반응형

이미지 보기 너비를 채우고 가로 세로 비율을 유지하도록 이미지 배율 조정

나는 있습니다GridView의 데이터GridView서버로부터의 요청입니다.

다음은 항목 레이아웃입니다.GridView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/analysis_micon_bg"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:paddingBottom="@dimen/half_activity_vertical_margin"
    android:paddingLeft="@dimen/half_activity_horizontal_margin"
    android:paddingRight="@dimen/half_activity_horizontal_margin"
    android:paddingTop="@dimen/half_activity_vertical_margin" >

    <ImageView
        android:id="@+id/ranking_prod_pic"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/app_name"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/ranking_rank_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/ranking_prod_num"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/ranking_prod_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

서버에서 데이터를 요청하여 이미지 URL을 가져오고 이미지를 로드합니다.Bitmap

public static Bitmap loadBitmapFromInputStream(InputStream is) {
    return BitmapFactory.decodeStream(is);
}

public static Bitmap loadBitmapFromHttpUrl(String url) {
    try {
        return loadBitmapFromInputStream((InputStream) (new URL(url).getContent()));
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
        return null;
    }
}

그리고 거기에는 코드가 있습니다.getView(int position, View convertView, ViewGroup parent)어댑터의 메서드

Bitmap bitmap = BitmapUtil.loadBitmapFromHttpUrl(product.getHttpUrl());
prodImg.setImageBitmap(bitmap);

이미지 크기는210*210나는 내 넥서스 4에서 애플리케이션을 실행합니다.이미지가 채워집니다.ImageView폭, 그러나ImageView높이가 조정되지 않습니다.ImageView전체 이미지를 표시하지 않습니다.

이 문제를 어떻게 해결해야 합니까?

사용자 지정 클래스 또는 라이브러리를 사용하지 않는 경우:

<ImageView
    android:id="@id/img"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter" />

scaleType="fitCenter"(누락 시 기본값)

  • 부모가 허용하는 한 폭을 넓히고 필요에 따라 가로 세로 비율을 유지할 수 있습니다.

scaleType="centerInside"

  • 의 본질적인 폭이라면src상위 너비보다 작습니다.
    이미지의 중앙을 수평으로 맞춥니다.
  • 의 본질적인 폭이라면src상위 너비보다 큼
    부모가 허용하는 한 폭을 넓히고 가로 세로 비율을 낮게 유지할 수 있습니다.

당신이 사용해도 상관없습니다.android:src또는ImageView.setImage*방법과 핵심은 아마도adjustViewBounds.

저는 arnefm의 답변을 좋아하지만 그가 작은 실수를 했습니다(댓글 참조). 제가 수정하려고 노력하겠습니다.

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * ImageView that keeps aspect ratio when scaled
 */
public class ScaleImageView extends ImageView {

  public ScaleImageView(Context context) {
    super(context);
  }

  public ScaleImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public ScaleImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
      Drawable drawable = getDrawable();
      if (drawable == null) {
        setMeasuredDimension(0, 0);
      } else {
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        if (measuredHeight == 0 && measuredWidth == 0) { //Height and width set to wrap_content
          setMeasuredDimension(measuredWidth, measuredHeight);
        } else if (measuredHeight == 0) { //Height set to wrap_content
          int width = measuredWidth;
          int height = width *  drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
          setMeasuredDimension(width, height);
        } else if (measuredWidth == 0){ //Width set to wrap_content
          int height = measuredHeight;
          int width = height * drawable.getIntrinsicWidth() / drawable.getIntrinsicHeight();
          setMeasuredDimension(width, height);
        } else { //Width and height are explicitly set (either to match_parent or to exact value)
          setMeasuredDimension(measuredWidth, measuredHeight);
        }
      }
    } catch (Exception e) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
  }

}

그러므로 당신의ImageView(예를 들어) 내부에 배치할 경우 치수 문제가 없고 적절하게 조정할 수 있습니다.ScrollView

저도 비슷한 문제가 있었어요.저는 커스텀 Image View를 만들어서 해결했습니다.

public class CustomImageView extends ImageView

그런 다음 이미지 보기의 onMeasure 메서드를 재정의합니다.저는 다음과 같은 일을 했습니다.

    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
        Drawable drawable = getDrawable();

        if (drawable == null) {
            setMeasuredDimension(0, 0);
        } else {
            float imageSideRatio = (float)drawable.getIntrinsicWidth() / (float)drawable.getIntrinsicHeight();
            float viewSideRatio = (float)MeasureSpec.getSize(widthMeasureSpec) / (float)MeasureSpec.getSize(heightMeasureSpec);
            if (imageSideRatio >= viewSideRatio) {
                // Image is wider than the display (ratio)
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int)(width / imageSideRatio);
                setMeasuredDimension(width, height);
            } else {
                // Image is taller than the display (ratio)
                int height = MeasureSpec.getSize(heightMeasureSpec);
                int width = (int)(height * imageSideRatio);
                setMeasuredDimension(width, height);
            }
        }
    } catch (Exception e) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

이렇게 하면 화면에 맞게 이미지가 늘어나며 가로 세로 비율은 유지됩니다.

사용하다android:scaleType="centerCrop".

FOR IMAGE VIEW(이 파라미터 설정)

android:layout_width     = "match_parent"
android:layout_height    = "wrap_content"
android:scaleType        = "fitCenter"
android:adjustViewBounds = "true"

이미지의 크기에 상관없이 이미지의 너비는 부모와 일치하고 높이는 비율과 일치합니다.저는 이것을 테스트했고 100% 확신합니다.

우리는 이것을 원합니다 -->

이것이 아니라 -->

// Results will be: 
Image width -> stretched as match parent
Image height -> according to image width (maximum to aspect ratio)

// like the first one

위와 비슷한 일을 하고 몇 시간 동안 벽에 머리를 부딪쳤습니다. 왜냐하면 그것은 내부에서 작동하지 않았기 때문입니다.RelativeLayout저는 결국 다음과 같은 코드를 얻었습니다.

package com.example;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class ScaledImageView extends ImageView {
    public ScaledImageView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        final Drawable d = getDrawable();

        if (d != null) {
            int width;
            int height;
            if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
                height = MeasureSpec.getSize(heightMeasureSpec);
                width = (int) Math.ceil(height * (float) d.getIntrinsicWidth() / d.getIntrinsicHeight());
            } else {
                width = MeasureSpec.getSize(widthMeasureSpec);
                height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
            }
            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

그리고 나서 예방하기 위해.RelativeLayout측정된 치수를 무시하는 것으로부터 저는 다음과 같이 했습니다.

    <FrameLayout
        android:id="@+id/image_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/something">

        <com.example.ScaledImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="150dp"/>
    </FrameLayout>

자바 코드는 필요 없습니다.다음과 같이 하면 됩니다.

<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop" />

키는 너비 및 높이에 대한 일치 상위 항목에 있습니다.

ImageView에서 이미지를 배경으로 설정한 경우에는 src(안드로이드:src)로 설정해야 합니다.

감사해요.

가로 폭이 화면 너비와 같고 가로 세로 비율에 따라 높이가 비례적으로 설정된 이미지를 만들려면 다음을 수행합니다.

Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

                        // creating the image that maintain aspect ratio with width of image is set to screenwidth.
                        int width = imageView.getMeasuredWidth();
                        int diw = resource.getWidth();
                        if (diw > 0) {
                            int height = 0;
                            height = width * resource.getHeight() / diw;
                            resource = Bitmap.createScaledBitmap(resource, width, height, false);
                        }
                                              imageView.setImageBitmap(resource);
                    }
                });

이게 도움이 되길 바랍니다.

ImageView에서 다음 속성을 사용하여 가로 세로 비율을 유지합니다.

android:adjustViewBounds="true"
android:scaleType="fitXY"

수동으로 이미지를 로드하여 현재 작업을 수행할 수 있지만 범용 이미지 로더를 보는 것이 좋습니다.

저는 최근에 그것을 제 프로젝트에 통합했고 그것은 환상적이라고 말해야 합니다.비동기화, 크기 조정, 이미지 캐싱에 대한 모든 우려가 있습니까?통합 및 설정이 정말 쉽습니다.5분 이내에 원하는 작업을 수행할 수 있습니다.

코드 예제:

//ImageLoader config
DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder().showStubImage(R.drawable.downloadplaceholder).cacheInMemory().cacheOnDisc().showImageOnFail(R.drawable.loading).build();

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).
            defaultDisplayImageOptions(displayimageOptions).memoryCache(new WeakMemoryCache()).discCache(new UnlimitedDiscCache(cacheDir)).build();

    if (ImageLoader.getInstance().isInited()) {
        ImageLoader.getInstance().destroy();
    }
    ImageLoader.getInstance().init(config);

    imageLoadingListener = new ImageLoadingListener() {
        @Override
        public void onLoadingStarted(String s, View view) {

        }

        @Override
        public void onLoadingFailed(String s, View view, FailReason failReason) {
            ImageView imageView = (ImageView) view;
            imageView.setImageResource(R.drawable.android);
            Log.i("Failed to Load " + s, failReason.toString());
        }

        @Override
        public void onLoadingComplete(String s, View view, Bitmap bitmap) {

        }

        @Override
        public void onLoadingCancelled(String s, View view) {

        }
    };

//Imageloader usage
ImageView imageView = new ImageView(getApplicationContext());
    if (orientation == 1) {
        imageView.setLayoutParams(new LinearLayout.LayoutParams(width / 6, width / 6));
    } else {
        imageView.setLayoutParams(new LinearLayout.LayoutParams(height / 6, height / 6));
    }
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageLoader.displayImage(SERVER_HOSTNAME + "demos" + demo.getPathRoot() + demo.getRootName() + ".png", imageView, imageLoadingListener);

이렇게 하면 이미지를 로드하는 작업이 느려지고 이미지 크기에 맞게 올바르게 조정할 수 있습니다. 로드하는 동안 자리 표시자 이미지를 표시하고 로드에 실패하여 리소스를 캐싱하는 경우 기본 아이콘을 표시합니다.

또한 이 현재 구성은 이미지 가로 세로 비율을 유지하므로 원래 질문에 적용할 수 있습니다.

이것을 사용해 보세요: 그것은 저에게 문제를 해결해 주었습니다.

   android:adjustViewBounds="true"
    android:scaleType="fitXY"

Universal Image Loader를 사용하여 설정하기만 하면 됩니다.

DisplayImageOptions.Builder()
    .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
    .build();

및 ImageView에 스케일 설정 없음

이 간단한 선으로 시도해 보세요...종속성 Android를 추가하지 않고 이미지 보기 태그의 xml 코드에 이 행을 추가합니다.scaleType="fitXY"

안드로이드 사용:ScaleType="fitX"Y" im ImageView xml

나도 비슷한 문제가 있었는데, 당신이 계산해야 하기 때문에 그 이유를 찾았습니다.dp에서 Android를 계산하고 있습니다.ImageView당신이 그것을 로드할 때.drawable그러나 비트맵에서 로드하는 것과 같은 다른 방법을 사용할 때는dp되지 않습니다.

여기 제 xml이 있습니다.

<ImageView
  android:id="@+id/imageViewer"
  android:layout_width="match_parent"
  android:layout_height="match_parent"//dp is not automaticly updated, when loading from a other source
  android:scaleType="fitCenter"
  tools:srcCompat="@drawable/a8" />

저는 코틀린을 사용하고 있고, 자산 파일에서 인출 가능한 것을 로드하고 있습니다. 제가 계산하는 방법은 다음과 같습니다.

val d = Drawable.createFromStream(assets.open("imageData/${imageName}.png"), null)
bitHeight = d.minimumHeight//get the image height
imageViewer.layoutParams.height = (bitHeight * resources.displayMetrics.density).toInt()//set the height
imageViewer.setImageDrawable(d)//set the image from the drawable
imageViewer.requestLayout()//here I apply it to the layout

언급URL : https://stackoverflow.com/questions/18077325/scale-image-to-fill-imageview-width-and-keep-aspect-ratio

반응형