I'd like to scale an image up to take up the entire size of an ImageView. This is subtly different than using scaleType=fit_center because fit_center will leave bands around the image if the image aspect ratio does not exactly match the ImageView's aspect ratio. Instead, I would like the image to get centered and scaled up to completely fill the enclosing view, with any excess chopped off.
I'm able to accomplish this by computing my own custom image matrix during onCreate():
final Display display = getWindowManager().getDefaultDisplay();
final float screenWidth = display.getWidth();
final float screenHeight = display.getHeight();
final float imageWidth = splashView.getDrawable().getIntrinsicWidth();
final float imageHeight = splashView.getDrawable().getIntrinsicHeight();
final Matrix splashMatrix = new Matrix();
final float scale = Math.max(screenHeight/imageHeight,screenWidth/imageWidth);
splashMatrix.postScale( scale, scale );
splashView.setImageMatrix(splashMatrix);
This works fine, but it seems like there must be an easier away. Does anyone know of a way to scale up an image in an ImageView while both preserving the aspect ratio of the image and fully filling in the ImageView?
(Note: in my case my ImageView is taking up the full screen, so I use getWindowManager().getDisplay() to find the desired image size. You can't use splashView.getWidth()/getHeight() because the view hasn't been laid out yet and doesn't have a size)
You can use android:scaleType="centerCrop".
Keeps the aspect ratio and scales the image just like you want it.
For more information please go through the below link
http://developer.android.com/reference/android/widget/ImageView.html#attr_android:scaleType
In some cases all you need is
android:adjustViewBounds="true"
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
This worked for me to fit the image inside the whole image view, plus it make sense that it says "ScaleType.FIT_XY" to fit the X and Y axis of the imageView.
From the xml file it would be:
android:scaleType="fitXY"
Try scaleType attribute for your ImageView. http://developer.android.com/reference/android/widget/ImageView.html#attr_android:scaleType
I am very late but hope it helps in the future. Here is my solution to how to stretch the image to full screen or image view without scaleType="fitXY" as it causes damage to the image. Use the following library.
[A simple imageview which scales the width or height aspect with the given ratio]
https://github.com/santalu/aspect-ratio-imageview
To Find the aspect ratio of the device screen use the following Code.
DisplayMetrics metrics =this.getResources().getDisplayMetrics();
float ratio = ((float)metrics.heightPixels / (float)metrics.widthPixels);
you must set android:scaleType="centerCrop" to fill entire screen
but you noticed that scaletype property worked together with android:layout_width and android:layout_height property.
you must set to match_parent
Related
As seen in this image:
I have a rounded rectangle that is the size of 1082 x 1796, and I used getWindowManager().getDefaultDisplay() to get and print the pixel values of the screen as seen in the circle bottom left. However, when I draw this bitmap, this happens:
Is the screen size different from the getDefaultDisplay() method? How do I fix this?
I think your shape is seen by the system as a 9patch. It use the first and last lines/columns in order to know how to resize the image in order to display it consistently.
That's why there is a 2px difference in width and height. I think you can correct it by modifying the png and removing the first and last lines/columns, or just use another way to draw the image. Maybe using another format (jpg ? bmp ?) for the image could do the job. I'm not sure.
you can do that with calculation to fit all screen devices based on width and height of the device screen:
DisplayMetrics dm = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = width * imageHeight / imageWidth;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
I want to stretch the image to fill width and adjust the height according to width and maintain the aspect ratio. I want it should cover entire width (fillparent) and height of imageview should adjust like in way so that aspect ratio is maintained.
I tried fit_xy but not working in my case. Please help me
There can two possible workarounds even if you set the scale type fit_xy
1) By default Android will scale your image down to fit the ImageView, maintaining the aspect ratio. However, make sure you're setting the image to the ImageView using android:src="..." rather than android:background="...". src= makes it scale the image maintaining aspect ratio, but background= makes it scale and distort the image to make it fit exactly to the size of the ImageView. (You can use a background and a source at the same time though, which can be useful for things like displaying a frame around the main image, using just one ImageView.)
2)You should also see android:adjustViewBounds to make the ImageView resize itself to fit the rescaled image. For example, if you have a rectangular image in what would normally be a square ImageView, adjustViewBounds=true will make it resize the ImageView to be rectangular as well. This then affects how other Views are laid out around the ImageView.
you can change the way it default scales images using the android:scaleType parameter. By the way, the easiest way to discover how this works would simply have been to experiment a bit yourself! Just remember to look at the layouts in the emulator itself (or an actual phone) as the preview in Eclipse is usually wrong.
I'm not sure when the feature I use was added to the Android SDK but there is a simple solution that does exactly what the OP is looking for:
As expected, set layout:width and layout:height to fill_parent.
As another responder mentioned correctly, use src to find your image, not background.
However instead of trying scaleType of fit_xy (which finds the narrowest side to fit into the view rather than the longest side), use scaleType of centerCrop.
centerCrop will center and fill in the viewport while retaining aspect ratio.
Hope this helps! I used it for the webView loading overlay of a commercial app I developed for my current employer.
Copy/paste solution: in your activity XML file, add the following lines:
<ImageView
android:id="#+id/logo"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/your_image_name"
/>
There are two ways of doing this:
First find the display height and width and call this method
private void scaleImage(int displayWidth) {
// Get the ImageView and its bitmap
width=displayWidth;
Drawable drawing = holder.imagepost.getDrawable();
{
Bitmap bitmap = ((BitmapDrawable) drawing).getBitmap();
int bounding = dpToPx(width);
// 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;
// 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);
// Apply the scaled bitmap
holder.imagepost.setImageDrawable(result);
// Now change ImageView's dimensions to match the scaled image
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.imagepost
.getLayoutParams();
params.width = width;
params.height = height;
holder.imagepost.setLayoutParams(params);
}
}
private int dpToPx(int dp) {
float density = context.getResources().getDisplayMetrics().density;
return Math.round((float) dp * density);
}
Or the Best way i know is to use Android Query
Here is the link http://code.google.com/p/android-query/ and you can download from there itself.Below id the code to maintain the Aspect Ratio
aq.id(R.id.imageView)
.image(imageString, true, true,
displaywidth, 0, null, AQuery.FADE_IN, AQuery.RATIO_PRESERVE);
Below solution is working fine for me.
Use AQuery Libray option "AQuery.RATIO_PRESERVE" to preserve aspect ratio:
aq.id(R.id.imgView).progress(R.id.imgPb).image(url, true, true,150, 0,null,AQuery.FADE_IN,AQuery.RATIO_PRESERVE);
Use below settings for ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
Use below settings for auto GridView Columns:
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:columnWidth="150dp"/>
I have an ImageView in my layout. Its width and height are both set to fill_parent. The scaleType is set to fitCenter. I am in landscape mode. So if I have a square src image, when scaled up it will display me two borders, on the left and on the right, which perfectly suits me. But how can I get the dimensions of these borders ? The dimensions of the bitmap won't help for sure, and the dimensions of the ImageView are equal to the screen's.
I have asked for intrinsicwidth but it seems to give me the width of the drawable before it has scaled up.
I have tried adjustViewBounds but the ImageView still fills all the parent.
Any idea ?
Thanks
make a RectF to represent the original picture size, scale it with a matrix into a new RectF, then use this to find your dimensions.
See my answer here Get drawable displayed size after scaling
on how to calculate displayed size for FIT_CENTER scaleType.
And for the calculating the border dimensions just substract calculated value and divide by 2 from the imageView dimesnsions.
So I have this task to create a horizontal scrolling array of image buttons that are basically photo avatars of users. These avatars aren't constrained by aspect ratio or size, and so I've been playing with ways to scale them and format them. I've gotten them scaling via the scaletype="fitCenter" and using static width and height. But what I really want them to do is to butt up against one another. Currently if an image is taller than it is high, you get the kind of letterboxing but on the sides vs. the top (blank areas). I've tried all the different scaling values, wrapping each imagemap within a linearlayout, etc., but nothing I try seems to get rid of those (while displaying the entire image to scale). Is there any way to do this?
Just to reiterate what I think you're doing, you have three image scenarios:
Square image
Landscape image (wider than tall)
Portrait image (taller than wide)
Laying out a row of fixed-size ImageViews (or ImageButtons) using FIT_CENTER works great for what you need if all the images were either square or landscape, because the scaling will always make the image stretch to the horizontal bounds of the view (the largest dimension). However, with portrait images, the scaling causes the view to be inside the bounds of your fixed-size view so that the entire image height can be visible.
If you need to maintain the aspect ratio of the image, there really is no ScaleType to help with this because the logic would be circular (fit the view to the image, while simultaneously fitting the image to the view). The solution is to adjust the size (specifically, the width) of each ImageView to match what the image will be scaled to. Here's a sample of a factory method you might use to generate the ImageView to fit the image you want to put inside it. You could also modify this slightly to reset parameters on an existing ImageView if you like:
private ImageView getImageViewForThumbnail(Bitmap thumbnail) {
float viewHeight = //Your chosen fixed view height
float scale = ((float)thumbnail.getHeight()) / viewHeight;
float viewWidth = thumbnail.getHeight() / scale;
ImageView view = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int)viewWidth, (int)viewHeight);
view.setLayoutParams(params);
view.setScaleType(ScaleType.FIT_XY);
view.setImageBitmap(thumbnail);
return view;
}
You're basically just calculating what the aspect width of the ImageView should be to match the fixed height you've chosen for all of them.
HTH
Use the scaleType fitXY, it stretches the image to the layout params you assigned, if the image has less dimensions and also shrinks the image to the layout params you assigned, if the image is large. The key point is to mention the image layout params to the imageView , that is the width and height of the image.
I want to scale an image in an ImageView in the following way. The ImageView has some dimensions Width (W) and Height (H). The image I'm putting into the image view could be smaller or bigger than WxH. I want it to scale while preserving aspect ratio to fill WxH space.
It seems like the closest thing to what I want is android:scaleType="centerInside", but what I'm seeing is that if the image is smaller than WxH, it will put a small-unscaled version of that image in the center of the ImageView (like the documentation says), but I want it to scale it to "fit", while showing the entire image, and stretching it to the maximum possible size of the container without cropping anything. In other words, stretch preserving aspect ratio until either the width or the height bumps into the edge of the container (ImageView).
This seems like an obvious thing to want to do, but I can't get it to work this way!!!
From the Android docs...
public static final Matrix.ScaleToFit CENTER
Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. The result is centered inside dst.
The XML attribute for this is...
android:scaleType="fitCenter"