pantalla - resolucion de imagenes en android studio
Ajustar la imagen en ImageView, mantener la relación de aspecto y luego cambiar el tamaño de ImageView a las dimensiones de la imagen? (13)
¿Cómo adaptar una imagen de tamaño aleatorio a un ImageView
?
Cuando:
- Inicialmente las dimensiones de
ImageView
son 250dp * 250dp - La dimensión más grande de la imagen debe ampliarse / reducirse a 250dp
- La imagen debe mantener su relación de aspecto
- Las dimensiones de
ImageView
deben coincidir con las dimensiones de la imagen escalada después de escalar
Por ejemplo, para una imagen de 100 * 150, la imagen y el ImageView
deben ser 166 * 250.
Por ejemplo, para una imagen de 150 * 100, la imagen y el ImageView
deben ser 250 * 166.
Si configuro los límites como
<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" />
las imágenes se ajustan correctamente en ImageView
, pero ImageView
siempre es 250dp * 250dp.
Después de buscar un día, creo que esta es la solución más fácil:
imageView.getLayoutParams().width = 250;
imageView.getLayoutParams().height = 250;
imageView.setAdjustViewBounds(true);
Editado Jarno Argillanders respuesta:
Cómo ajustar la imagen con su ancho y alto:
1) Inicializa ImageView y establece Imagen:
iv = (ImageView) findViewById(R.id.iv_image);
iv.setImageBitmap(image);
2) Ahora cambie el tamaño:
scaleImage(iv);
Método de scaleImage
editado: ( puede reemplazar valores de límite ESPERADOS )
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);
}
Y .xml:
<ImageView
android:id="@+id/iv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
El código Abajo hace que el mapa de bits se ajuste perfectamente al mismo tamaño de la vista de la imagen. Obtenga la altura y el ancho de la imagen de mapa de bits y luego calcule la nueva altura y ancho con la ayuda de los parámetros de la vista de imagen. Eso le da la imagen requerida con la mejor relación de aspecto.
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)
disfrutar.
Esto lo hizo por mi caso.
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
/>
La mejor solución que funciona en la mayoría de los casos es
Aquí hay un ejemplo:
<ImageView android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
Necesitaba hacer esto en un diseño restringido con Picasso, así que reuní algunas de las respuestas anteriores y obtuve esta solución (ya sé la relación de aspecto de la imagen que estoy cargando, así que eso ayuda):
Invocado en mi código de actividad en algún lugar después de 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...
}
}
En mi 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>
Tenga en cuenta la falta de un atributo constraintBottom_toBottomOf. ImageLoader es mi propia clase estática para los métodos y constantes de carga de imágenes.
Necesitaba tener un ImageView y un mapa de bits, por lo que el mapa de bits se escala a tamaño de ImageView, y el tamaño de ImageView es el mismo del mapa de bits escalado :).
Estaba mirando esta publicación para saber cómo hacerlo, y finalmente hice lo que quería, aunque no del modo descrito aquí.
<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" />
y luego en el método 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;
}
y luego el código 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);
}
Y el resultado es que la imagen encaja perfectamente en el interior, manteniendo la relación de aspecto, y no tiene píxeles sobrantes adicionales de ImageView cuando el mapa de bits está dentro.
Es importante que ImageView tenga wrap_content y adjustViewBounds en true, luego setMaxWidth y setMaxHeight funcionarán, esto está escrito en el código fuente de 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. */
Puede que no responda a esta pregunta específica, pero si alguien, como yo, busca una respuesta sobre cómo ajustar la imagen en ImageView con un tamaño limitado (por ejemplo, maxWidth
) mientras conserva la relación de aspecto y luego elimina el exceso de espacio ocupado por ImageView. entonces la solución más simple es usar las siguientes propiedades en XML:
android:scaleType="centerInside"
android:adjustViewBounds="true"
Usa este código:
<ImageView android:id="@+id/avatar"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
intente agregar android:scaleType="fitXY"
a su ImageView
.
todo esto se puede hacer usando XML ... los otros métodos parecen bastante complicados. De todos modos, simplemente establece la altura en lo que quieras en dp, luego configura el ancho para ajustar el contenido o viceversa. Use scaleType fitCenter para ajustar el tamaño de la imagen.
<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">
(La respuesta fue muy modificada después de las aclaraciones a la pregunta original)
Después de aclaraciones:
Esto no se puede hacer solo en xml . No es posible escalar tanto la imagen como el ImageView
para que la única dimensión de la imagen sea siempre de 250dp y el ImageView
tenga las mismas dimensiones que la imagen.
Este código escala Drawable
de un ImageView
para permanecer en un cuadrado como 250dp x 250dp con una dimensión exactamente 250dp y manteniendo la relación de aspecto. Luego, ImageView
se redimensiona para que coincida con las dimensiones de la imagen escalada. El código se usa en una actividad. Lo probé a través de un clic en el controlador de clic.
Disfrutar. :)
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);
}
El código xml para 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"/>
Gracias a esta discusión para el código de escala:
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html
ACTUALIZACIÓN 7 de noviembre de 2012:
Se agregó una verificación del puntero nulo como se sugiere en los comentarios
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>