ランダムサイズの画像をImageView
に合わせるにはどうすればいいですか?
いつ:
ImageView
の寸法は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のみではできません。 imageとImageView
の両方を拡大縮小して、imageの1つの寸法が常に250dpになり、ImageView
がimageと同じ寸法になるようにすることはできません。
このコードは、Drawable
のImageView
を、縦横比を保ちながら1次元が250dp x 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);
}
ImageView
のxmlコード:
<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日:
コメントで示唆されているようにnullポインタチェックを追加しました
この特定の質問に対する回答ではないかもしれませんが、私のように、縦横比を維持しながらImageViewに画像を収まるサイズ(たとえばmaxWidth
)にし、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でビットマップを完全に作ります。ビットマップ画像の高さと幅を取得してから、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)
楽しい。
ImageView
にAndroid:scaleType="fitXY"
を追加してみてください。
一日を検索した後、私はこれが最も簡単な解決策だと思います:
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を初期化してImageを設定します。
iv = (ImageView) findViewById(R.id.iv_image);
iv.setImageBitmap(image);
2)今サイズ変更:
scaleImage(iv);
scaleImage
メソッドを編集しました:(あなたは期待された境界値を置き換えることができます)
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から余計なピクセルが残りません。
Wrap_contentとadjustViewBoundsをtrueにすることはImageViewにとって重要です。それから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. */
単純な数学を使用して画像のサイズを変更します。 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" />
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);
私の写真はgridviewに動的に追加されます。 imageviewにこれらの設定をするとき、絵は自動的に1:1の比率で表示されることができます。