1. ホーム
  2. android

[解決済み] ImageViewに画像をはめ込み、アスペクト比を維持したまま、ImageViewを画像の寸法にリサイズしますか?

2022-04-13 12:57:22

質問

ランダムな大きさの画像を ImageView ?

いつ

  • 当初は ImageView 寸法は250dp×250dp
  • 画像の大きい方の寸法を250dpに拡大・縮小してください。
  • 画像のアスペクト比を維持する
  • ImageView の寸法は、スケーリング後の画像の寸法と一致する必要があります。

例:100*150の画像の場合、画像と ImageView は166*250にする必要があります。

例:150*100の画像の場合、画像と ImageView は250*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 は、画像と同じ寸法になります。

このコードでは DrawableImageView を250dp×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日に更新しました。

コメントで示唆されたヌルポインタのチェックを追加