IT박스

이미지를 ImageView에 맞추고 종횡비를 유지 한 다음 ImageView의 크기를 이미지 크기로 조정 하시겠습니까?

itboxs 2020. 6. 9. 22:19
반응형

이미지를 ImageView에 맞추고 종횡비를 유지 한 다음 ImageView의 크기를 이미지 크기로 조정 하시겠습니까?


임의의 크기의 이미지를에 맞추는 방법은 ImageView무엇입니까?
언제:

  • 초기 ImageView크기는 250dp * 250dp입니다
  • 이미지의 더 큰 치수는 250dp로 확대 / 축소되어야합니다
  • 이미지의 가로 세로 비율을 유지해야합니다
  • ImageView차원은 스케일링 후 스케일 이미지의 크기와 일치해야

예를 들어 100 * 150 이미지의 경우 이미지와 ImageView166 * 250이어야합니다.
예를 들어 150 * 100 이미지의 경우 이미지와 ImageView250 * 166이어야합니다.

경계를 다음과 같이 설정하면

<ImageView
    android:id="@+id/picture"
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:adjustViewBounds="true" />

이미지가 제대로 맞지 ImageView하지만은 ImageView항상 250dp * 250dp입니다.


(원래 질문에 대한 설명을 한 후 답변이 크게 수정되었습니다)

해명 후 :
이것은 단지 XML로 수행 할 수 없습니다 . ImageView이미지의 한 치수가 항상 250dp이고 이미지와 치수가 같아 지도록 이미지와 크기를 모두 조정할 수는 없습니다 ImageView.

이 코드는 크기 DrawableImageView250dp x 250dp와 같은 정사각형에 정확히 250dp로 유지되고 종횡비를 유지하도록 확장됩니다. 그런 다음 ImageView크기가 조정 된 이미지의 크기와 일치하도록 크기가 조정됩니다. 코드는 활동에 사용됩니다. 버튼 클릭 핸들러를 통해 테스트했습니다.

즐겨. :)

private void scaleImage(ImageView view) throws NoSuchElementException  {
    // Get bitmap from the the ImageView.
    Bitmap bitmap = null;

    try {
        Drawable drawing = view.getDrawable();
        bitmap = ((BitmapDrawable) drawing).getBitmap();
    } catch (NullPointerException e) {
        throw new NoSuchElementException("No drawable on given view");
    } catch (ClassCastException e) {
        // Check bitmap is Ion drawable
        bitmap = Ion.with(view).getBitmap();
    }

    // Get current dimensions AND the desired bounding box
    int width = 0;

    try {
        width = bitmap.getWidth();
    } catch (NullPointerException e) {
        throw new NoSuchElementException("Can't find bitmap on given view/drawable");
    }

    int height = bitmap.getHeight();
    int bounding = dpToPx(250);
    Log.i("Test", "original width = " + Integer.toString(width));
    Log.i("Test", "original height = " + Integer.toString(height));
    Log.i("Test", "bounding = " + Integer.toString(bounding));

    // Determine how much to scale: the dimension requiring less scaling is
    // closer to the its side. This way the image always stays inside your
    // bounding box AND either x/y axis touches it.  
    float xScale = ((float) bounding) / width;
    float yScale = ((float) bounding) / height;
    float scale = (xScale <= yScale) ? xScale : yScale;
    Log.i("Test", "xScale = " + Float.toString(xScale));
    Log.i("Test", "yScale = " + Float.toString(yScale));
    Log.i("Test", "scale = " + Float.toString(scale));

    // Create a matrix for the scaling and add the scaling data
    Matrix matrix = new Matrix();
    matrix.postScale(scale, scale);

    // Create a new bitmap and convert it to a format understood by the ImageView 
    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    width = scaledBitmap.getWidth(); // re-use
    height = scaledBitmap.getHeight(); // re-use
    BitmapDrawable result = new BitmapDrawable(scaledBitmap);
    Log.i("Test", "scaled width = " + Integer.toString(width));
    Log.i("Test", "scaled height = " + Integer.toString(height));

    // Apply the scaled bitmap
    view.setImageDrawable(result);

    // Now change ImageView's dimensions to match the scaled image
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); 
    params.width = width;
    params.height = height;
    view.setLayoutParams(params);

    Log.i("Test", "done");
}

private int dpToPx(int dp) {
    float density = getApplicationContext().getResources().getDisplayMetrics().density;
    return Math.round((float)dp * density);
}

의 XML 코드 ImageView:

<ImageView a:id="@+id/image_box"
    a:background="#ff0000"
    a:src="@drawable/star"
    a:layout_width="wrap_content"
    a:layout_height="wrap_content"
    a:layout_marginTop="20dp"
    a:layout_gravity="center_horizontal"/>


스케일링 코드에 대한 다음 토론 덕분에
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html


2012 년 11 월 7 일 업데이트 :
의견에서 제안한대로 널 포인터 검사가 추가되었습니다.


이 특정 질문에 대한 답은 아니지만 누군가가 나와 같은 경우 maxWidth가로 세로 비율을 유지하면서 ImageView에서 이미지를 경계 크기 (예 :)로 맞추고 ImageView가 차지하는 과도한 공간을 제거 하는 방법에 대한 답변을 검색하는 경우 가장 간단한 해결책은 XML에서 다음 속성을 사용하는 것입니다.

    android:scaleType="centerInside"
    android:adjustViewBounds="true"

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

아래 코드는 비트 맵을 동일한 크기의 이미지 뷰로 완벽하게 만듭니다. 비트 맵 이미지 높이와 너비를 얻은 다음 imageview의 매개 변수를 사용하여 새 높이와 너비를 계산하십시오. 화면비가 가장 좋은 이미지를 얻을 수 있습니다.

int currentBitmapWidth = bitMap.getWidth();
int currentBitmapHeight = bitMap.getHeight();

int ivWidth = imageView.getWidth();
int ivHeight = imageView.getHeight();
int newWidth = ivWidth;

newHeight = (int) Math.floor((double) currentBitmapHeight *( (double) new_width / (double) currentBitmapWidth));

Bitmap newbitMap = Bitmap.createScaledBitmap(bitMap, newWidth, newHeight, true);

imageView.setImageBitmap(newbitMap)

즐겨.


추가하려고 android:scaleType="fitXY"당신에 ImageView.


하루를 검색 한 후 이것이 가장 쉬운 해결책이라고 생각합니다.

imageView.getLayoutParams().width = 250;
imageView.getLayoutParams().height = 250;
imageView.setAdjustViewBounds(true);

대부분의 경우 가장 적합한 솔루션은

예를 들면 다음과 같습니다.

<ImageView android:id="@+id/avatar"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY"/>

이것은 모두 XML을 사용하여 수행 할 수 있습니다 ... 다른 방법은 꽤 복잡해 보입니다. 어쨌든 dp에서 원하는 높이를 설정 한 다음 내용을 감싸거나 너비를 줄이려면 너비를 설정하십시오. scaleType fitCenter를 사용하여 이미지 크기를 조정하십시오.

<ImageView
    android:layout_height="200dp"
    android:layout_width="wrap_content"
    android:scaleType="fitCenter"
    android:adjustViewBounds="true"
    android:src="@mipmap/ic_launcher"
    android:layout_below="@+id/title"
    android:layout_margin="5dip"
    android:id="@+id/imageView1">

이 코드를 사용하십시오 :

<ImageView android:id="@+id/avatar"
           android:layout_width="fill_parent"
           android:layout_height="match_parent"
           android:scaleType="fitXY" />

편집 된 Jarno Argillanders 답변 :

너비와 높이에 이미지를 맞추는 방법 :

1) ImageView를 초기화하고 이미지를 설정하십시오.

iv = (ImageView) findViewById(R.id.iv_image);
iv.setImageBitmap(image);

2) 이제 크기를 조정하십시오.

scaleImage(iv);

편집 된 scaleImage방법 : ( EXPECTED 경계 값을 대체 할 수 있음 )

private void scaleImage(ImageView view) {
    Drawable drawing = view.getDrawable();
    if (drawing == null) {
        return;
    }
    Bitmap bitmap = ((BitmapDrawable) drawing).getBitmap();

    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int xBounding = ((View) view.getParent()).getWidth();//EXPECTED WIDTH
    int yBounding = ((View) view.getParent()).getHeight();//EXPECTED HEIGHT

    float xScale = ((float) xBounding) / width;
    float yScale = ((float) yBounding) / height;

    Matrix matrix = new Matrix();
    matrix.postScale(xScale, yScale);

    Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    width = scaledBitmap.getWidth();
    height = scaledBitmap.getHeight();
    BitmapDrawable result = new BitmapDrawable(context.getResources(), scaledBitmap);

    view.setImageDrawable(result);

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); 
    params.width = width;
    params.height = height;
    view.setLayoutParams(params);
}

그리고 .xml :

<ImageView
    android:id="@+id/iv_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" />

이것은 나의 경우를 위해 그것을했다.

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

ImageView와 Bitmap이 필요했기 때문에 Bitmap은 ImageView 크기로 조정되고 ImageView의 크기는 조정 된 Bitmap과 동일합니다. :)

나는이 게시물을 통해 그것을 수행하는 방법을 찾고 있었고 마침내 여기에 설명 된 방식이 아니라 내가 원하는 것을했습니다.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/acpt_frag_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/imageBackground"
android:orientation="vertical">

<ImageView
    android:id="@+id/acpt_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:layout_margin="@dimen/document_editor_image_margin"
    android:background="@color/imageBackground"
    android:elevation="@dimen/document_image_elevation" />

그런 다음 onCreateView 메소드에서

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_scanner_acpt, null);

    progress = view.findViewById(R.id.progress);

    imageView = view.findViewById(R.id.acpt_image);
    imageView.setImageBitmap( bitmap );

    imageView.getViewTreeObserver().addOnGlobalLayoutListener(()->
        layoutImageView()
    );

    return view;
}

그런 다음 layoutImageView () 코드

private void layoutImageView(){

    float[] matrixv = new float[ 9 ];

    imageView.getImageMatrix().getValues(matrixv);

    int w = (int) ( matrixv[Matrix.MSCALE_X] * bitmap.getWidth() );
    int h = (int) ( matrixv[Matrix.MSCALE_Y] * bitmap.getHeight() );

    imageView.setMaxHeight(h);
    imageView.setMaxWidth(w);

}

결과적으로 이미지는 종횡비를 유지하면서 완벽하게 들어가고 비트 맵이있을 때 ImageView에서 남은 픽셀이 없습니다.

결과

ImageView가 wrap_content 및 adjustViewBounds를 true로 설정하는 것이 중요합니다. 그러면 setMaxWidth 및 setMaxHeight가 작동합니다. 이는 ImageView의 소스 코드로 작성됩니다.

/*An optional argument to supply a maximum height for this view. Only valid if
 * {@link #setAdjustViewBounds(boolean)} has been set to true. To set an image to be a
 * maximum of 100 x 100 while preserving the original aspect ratio, do the following: 1) set
 * adjustViewBounds to true 2) set maxWidth and maxHeight to 100 3) set the height and width
 * layout params to WRAP_CONTENT. */

Picasso를 사용하여 제약 조건 레이아웃 에서이 작업을 수행해야 했으므로 위의 답변 중 일부를 정리 하고이 솔루션을 생각해 냈습니다 (로드하는 이미지의 종횡비를 이미 알고 있으므로 도움이됩니다).

setContentView (...) 다음에 어딘가에 내 활동 코드에서 호출되었습니다.

protected void setBoxshotBackgroundImage() {
    ImageView backgroundImageView = (ImageView) findViewById(R.id.background_image_view);

    if(backgroundImageView != null) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int width = displayMetrics.widthPixels;
        int height = (int) Math.round(width * ImageLoader.BOXART_HEIGHT_ASPECT_RATIO);

        // we adjust the height of this element, as the width is already pinned to the parent in xml
        backgroundImageView.getLayoutParams().height = height;

        // implement your Picasso loading code here
    } else {
        // fallback if no element in layout...
    }
}

내 XML에서

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteY="0dp"
tools:layout_editor_absoluteX="0dp">

    <ImageView
        android:id="@+id/background_image_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitStart"
        app:srcCompat="@color/background"
        android:adjustViewBounds="true"
        tools:layout_editor_absoluteY="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginBottom="0dp"
        android:layout_marginRight="0dp"
        android:layout_marginLeft="0dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- other elements of this layout here... -->

</android.support.constraint.ConstraintLayout>

constraintBottom_toBottomOf 속성이 부족합니다. ImageLoader 는 이미지 로딩 util 메소드와 상수를위한 제 자신의 정적 클래스입니다.


매우 간단한 솔루션을 사용하고 있습니다. 여기 내 코드 :

imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.getLayoutParams().height = imageView.getLayoutParams().width;
imageView.setMinimumHeight(imageView.getLayoutParams().width);

내 사진은 격자보기에서 동적으로 추가됩니다. 이러한 설정을 이미지보기로 설정하면 사진이 자동으로 1 : 1 비율로 표시 될 수 있습니다.


간단한 수학을 사용하여 이미지 크기를 조정하십시오. ImageView설정된 것보다 드로어 블 이미지의 크기를 조정 하거나 크기를 조정할 수 있습니다 ImageView. 설정하려는 비트 맵의 ​​너비와 높이를 찾고 ImageView원하는 메소드를 호출하십시오. 너비 500이 호출 메소드보다 높이보다 크다고 가정하십시오.

//250 is the width you want after resize bitmap
Bitmat bmp = BitmapScaler.scaleToFitWidth(bitmap, 250) ;
ImageView image = (ImageView) findViewById(R.id.picture);
image.setImageBitmap(bmp);

비트 맵 크기 조정에이 클래스를 사용합니다.

public class BitmapScaler{
// Scale and maintain aspect ratio given a desired width
// BitmapScaler.scaleToFitWidth(bitmap, 100);
 public static Bitmap scaleToFitWidth(Bitmap b, int width)
  {
    float factor = width / (float) b.getWidth();
    return Bitmap.createScaledBitmap(b, width, (int) (b.getHeight() * factor), true);
  }


  // Scale and maintain aspect ratio given a desired height
  // BitmapScaler.scaleToFitHeight(bitmap, 100);
  public static Bitmap scaleToFitHeight(Bitmap b, int height)
  {
    float factor = height / (float) b.getHeight();
    return Bitmap.createScaledBitmap(b, (int) (b.getWidth() * factor), height, true);
   }
 }

xml 코드는

<ImageView
android:id="@+id/picture"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:adjustViewBounds="true"
android:scaleType="fitcenter" />

그것이 작동하지 않으면 android : background를 android : src로 바꾸십시오.

android : src는 주요 트릭을 재생합니다

    <ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter"
    android:src="@drawable/bg_hc" />

그것은 매력처럼 잘 작동합니다

여기에 이미지 설명을 입력하십시오

참고 URL : https://stackoverflow.com/questions/8232608/fit-image-into-imageview-keep-aspect-ratio-and-then-resize-imageview-to-image-d

반응형