How to scale an Image in ImageView to keep the aspect ratio - android

In Android, I defined an ImageView's layout_width to be fill_parent (which takes up the full width of the phone).
If the image I put to ImageView is bigger than the layout_width, Android will scale it, right? But what about the height? When Android scales the image, will it keep the aspect ratio?
What I find out is that there is some white space at the top and bottom of the ImageView when Android scales an image which is bigger than the ImageView. Is that true? If yes, how can I eliminate that white space?

Yes, 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.)
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.
Then as Samuh wrote, 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.

See android:adjustViewBounds.
Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable.

To anyone else having this particular issue. You have an ImageView that you want to have a width of fill_parent and a height scaled proportionately:
Add these two attributes to your ImageView:
android:adjustViewBounds="true"
android:scaleType="centerCrop"
And set the ImageView width to fill_parent and height to wrap_content.
Also, if you don't want your image to be cropped, try this:
android:adjustViewBounds="true"
android:layout_centerInParent="true"

If you want an ImageView that both scales up and down while keeping the proper aspect ratio, add this to your XML:
android:adjustViewBounds="true"
android:scaleType="fitCenter"
Add this to your code:
// We need to adjust the height if the width of the bitmap is
// smaller than the view width, otherwise the image will be boxed.
final double viewWidthToBitmapWidthRatio = (double)image.getWidth() / (double)bitmap.getWidth();
image.getLayoutParams().height = (int) (bitmap.getHeight() * viewWidthToBitmapWidthRatio);
It took me a while to get this working, but this appears to work in the cases both where the image is smaller than the screen width and larger than the screen width, and it does not box the image.

This worked for me:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="39dip"
android:scaleType="centerCrop"
android:adjustViewBounds ="true"

This is how it worked for me inside a ConstraintLayout:
<ImageView
android:id="#+id/myImg"
android:layout_width="300dp"
android:layout_height="300dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"/>
Then in code, I set the drawable as:
ImageView imgView = findViewById(R.id.myImg);
imgView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.image_to_show, null));
This fits the image nicely according to its aspect ratio and keeps it in centre.

this solved my problem
android:adjustViewBounds="true"
android:scaleType="fitXY"

Take a look at ImageView.ScaleType to control and understand the way resizing happens in an ImageView. When the image is resized (while maintaining its aspect ratio), chances are that either the image's height or width becomes smaller than ImageView's dimensions.

Below code Working for scale image as aspect ratio:
Bitmap bitmapImage = BitmapFactory.decodeFile("Your path");
int nh = (int) ( bitmapImage.getHeight() * (512.0 / bitmapImage.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(bitmapImage, 512, nh, true);
your_imageview.setImageBitmap(scaled);

I have an image smaller than the screen. To have it stretched proportionally to the max and centered in the view I had to use the following code:
<ImageView
android:id="#+id/my_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:layout_weight="1"
android:scaleType="fitCenter" />
Have in mind though, that if you have a relative layout and have some elements set to be above or below the ImageView, they will be most likely overlapped by the image.

Use these properties in ImageView to keep aspect ratio:
android:adjustViewBounds="true"
android:scaleType="fitXY"
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>

If image quality decreases in:
use
android:adjustViewBounds="true"
instead of
android:adjustViewBounds="true"
android:scaleType="fitXY"

For anyone of you who wants the image to fit exact the imageview with proper scaling and no cropping use
imageView.setScaleType(ScaleType.FIT_XY);
where imageView is the view representing your ImageView

You can calculate screen width. And you can scale bitmap.
public static float getScreenWidth(Activity activity) {
Display display = activity.getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
float pxWidth = outMetrics.widthPixels;
return pxWidth;
}
calculate screen width and scaled image height by screen width.
float screenWidth=getScreenWidth(act)
float newHeight = screenWidth;
if (bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
newHeight = (screenWidth * bitmap.getHeight()) / bitmap.getWidth();
}
After you can scale bitmap.
Bitmap scaledBitmap=Bitmap.createScaledBitmap(bitmap, (int) screenWidth, (int) newHeight, true);

When doing this programmatically, be sure to call the setters in the correct order:
imageView.setAdjustViewBounds(true)
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP)

If you want your image occupy the maximum possible space then the best option would be
android:layout_weight="1"
android:scaleType="fitCenter"

Yo don't need any java code. You just have to :
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
The key is in the match parent for width and height

I use this:
<ImageView
android:id="#+id/logo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="centerInside"
android:src="#drawable/logo" />

Try using android:layout_gravity for ImageView:
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1"
The example above worked for me.

I have an algorithm to scale a bitmap to bestFit the container dimensions, maintaining its aspect ratio. Please find my solution here
Hope this helps someone down the lane!

Pass your ImageView and based on screen height and width you can make it
public void setScaleImage(EventAssetValueListenerView view){
// Get the ImageView and its bitmap
Drawable drawing = view.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float xScale = ((float) 4) / width;
float yScale = ((float) 4) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
BitmapDrawable result = new BitmapDrawable(scaledBitmap);
width = scaledBitmap.getWidth();
height = scaledBitmap.getHeight();
view.setImageDrawable(result);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
}

Programatically apply aspect ratio to Imageview:
aspectRatio = imageWidth/imageHeight
ratioOfWidth = imageWidth/maxWidth
ratioOfHeight = imageHeight/maxHeight
if(ratioOfWidth > ratioOfHeight){​​​​​​​
imageWidth = maxWidth
imageHeight = imageWidth/aspectRatio
}​​​​​​​ else if(ratioOfHeight > ratioOfWidth){​​​​​​​
imageHeight = maxHeight
imageWidth = imageHeight * aspectRatio
}​​​​​​​
After that you can use scaled bitmap to image view
Bitmap scaledBitmap= Bitmap.createScaledBitmap(bitmap, (int) imageWidth , (int) imageHeight , true);

in case of using cardviewfor rounding imageview and fixed android:layout_height for header this worked for me to load image with Glide
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="220dp"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
>
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|top"
card_view:cardBackgroundColor="#color/colorPrimary"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true">
<ImageView
android:adjustViewBounds="true"
android:maxHeight="220dp"
android:id="#+id/iv_full"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"/>
</android.support.v7.widget.CardView>
</FrameLayout>

You can scale image that will also reduce the size of your image.
There is a library for it you can download and use it.
https://github.com/niraj124124/Images-Files-scale-and-compress.git
How to use
1)Import the compressor-v1.0. jar to your project.
2)Add the below sample code to test.
ResizeLimiter resize = ImageResizer.build();
resize.scale("inputImagePath", "outputImagePath",imageWidth, imageHeight);
Many more methods are there according to your requirement

Quick answer:
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="#drawable/yourImage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

imageView.setImageBitmap(Bitmap.createScaledBitmap(bitmap, 130, 110, false));

Related

Handle ImageView size on screen rotation

This is not much of a problem but a requirement of an application I'm working on. I have an activity and a fragment inside that activity. This is the layout of a fragment:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
tools:context=".NavigationActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/avaImage"
android:layout_width="687dp"
android:layout_height="438dp"
android:gravity="right|center_vertical"
android:layout_above="#+id/txtLabel"
android:layout_marginTop="40dp"
/>
<TextView
android:id="#+id/txtLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="92dp"
android:layout_marginTop="20dp"
android:text="Available"
android:textSize="26sp" />
</RelativeLayout>
</ScrollView>
I'm including a drawable resource as the imageView's src programatically.
ImageView image = (ImageView) rootView.findViewById(R.id.avaImage);
image.setImageDrawable(getResources().getDrawable(R.drawable.availability_green));
The image works pretty nicely in a portrait orientation but in landscape, the image is shrunk.
So, my question is, is there any way to control how much the image would shrink on screen rotation making sure it'd show the same way across Android devices?
Use ImageView.ScaleType to specify how your image will handle size changes. This two properties will keep the original aspect ratio:
CENTER_INSIDE
Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding).
CENTER_CROP
Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).
Try this code:
#Override
public void onConfigurationChanged( Configuration newConfig)
{
super.onConfigurationChanged( newConfig);
SCREEN_WIDTH = contextApplication.getResources().getDisplayMetrics().widthPixels;
SCREEN_HEIGHT = contextApplication.getResources().getDisplayMetrics().heightPixels;
if( SCREEN_WIDTH < SCREEN_HEIGHT) // portret
{
image.setAdjustViewBounds( true);
image.setScaleType( ScaleType.CENTER_INSIDE);
image.setMaxWidth( 10);
image.setMinimumWidth( 10);
image.setMaxHeight( 10);
image.setMinimumHeight( 10);
}
else // land or square (if this is exist :) )
{
image.setAdjustViewBounds( true);
image.setScaleType( ScaleType.CENTER_INSIDE);
image.setMaxWidth( 20);
image.setMinimumWidth( 20);
image.setMaxHeight( 20);
image.setMinimumHeight( 20);
}
}
And add android:configChanges="keyboardHidden|orientation" to activity in AndroidMainfest

Why do I need to wrap an ImageView into a FrameLayout?

Here is a simple layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="40dp" <!-- notice I've limited a height -->
android:scaleType="fitStart"
android:adjustViewBounds="true"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/companyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/companyIcon"
android:layout_marginLeft="3dp"
android:layout_centerVertical="true"
android:textStyle="bold"
android:textColor="#20526d" />
</RelativeLayout>
The height of an image I will set by setImageBitmap() is more that 40dp.
Using this layout I have an extra space between ImageView and TextView, where did it come from?
But after I wrap the ImageView with FrameLayout I don't have this unnecessary extra space:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:id="#+id/image_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:scaleType="fitStart"
android:adjustViewBounds="true"
android:layout_alignParentLeft="true" />
</FrameLayout>
<TextView
android:id="#+id/companyName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/image_container"
android:layout_marginLeft="3dp"
android:layout_centerVertical="true"
android:textStyle="bold"
android:textColor="#20526d" />
</RelativeLayout>
And the result:
Can you guys explain why shall I put ImageView into FrameLayout to have things as intended? Thank you very much.
The height of an image I will set by setImageBitmap() is more that 40dp. Using this layout I have an extra space between ImageView and TextView, where did it come from?
Since the android:layout_height="40dp" with a android:scaleType="fitStart", the image is getting scaled down (and to the left/start) to fit the height, so this "extra space" is actually the original width of the image, since your android:layout_width="wrap_content". I recreated your layout with my own image that is larger than 40dp. When you select the ImageView, you can see that its bounds stretch to the image's original width.
To further prove this, if I set android:scaleType="center", no fit is applied and you can see the ImageView's original width.
Can you guys explain why shall I put ImageView into FrameLayout to have things as intended?
It appears that since your FrameLayout uses android:layout_width="wrap_content", it gets the correct scaled down width from your ImageView after it gets scaled due to android:adjustViewBounds="true". It is strange that the ImageView itself uses android:layout_width="wrap_content", but shows the original image's width, and not the scaled width. My hunch is that the height and width of ImageViews get set before the scaling is applied, so the ImageView gets the original image's width, but the parent FrameLayout gets the scaled width of it's ImageView child after the scaling is applied. This may not be true, but it appears that way to me.
However, you can solve the unscaled width issue (without using a FrameLayout) by using android:maxHeight="40dp" on the ImageView. You can then set android:layout_height="wrap_content" so your images can be smaller than 40dp if the image is smaller.
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:maxHeight="40dp"
android:scaleType="fitStart" />
This applies to almost all the view but answer is written considering specifically ImageView
Guideline to set Height and Width
Choose one of this three options only.
Set both height and width to "WRAP_CONTENT"
Set both height and
width to "FILL_PARENT"
Set both height and width to "FIXED SIZE"
*Avoid using mixture of them say Width=WRAP_CONTENT and Height=FILL_PARENT
Guideline to set SCALETYPE for ImageView
What does ScaleType do?
It scale the image you set to the ImageView, It doesn't scale
ImageView so when you set it to fitStart it will scale your image and
show on the right but your imageView will remain same in terms of
height and width as what you have specified.
As if you are using WRAP_CONTENT for height and width you don't need to specify ScaleType cause your ImageView is automatically going to be as big as your image.
As if you are using FILL_PARENT for height and width you will have option to show the image in Center,Start,End or in Full view.. so based on that you can choose your ScaleType.
As if you are using FIXED_SIZE fpr height and width you should opt for scaletype=FITXY.
Guideline to set Image into ImageView
As if you are setting image statically in XML then you have one image on your hand so you can create image of the size you wish as per your layout design and just move on with WRAP_CONTENT.
As if you are setting image at runtime after downloading it from somewhere, that time download the image and create bitmap of the size you prefer and then set it to ImageView
Specific to your case
You can see that your image is quite stretched and the text is not readable that's because you have downloaded and set image as it is but in smaller height and width.. rather you should have done like,
Set ImageView height and width to WRAP_CONTENT in XML file
<ImageView
android:id="#+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" />
Download image in your required size say 50X100, for example see this code
class LoadPics extends AsyncTask<Void, Bitmap, Bitmap> {
String urlStr;
ImageView iv;
int width, height;
public LoadPics(ImageView iv, String url, int width, int height) {
this.iv = iv;
this.urlStr = url;
this.width = width;
this.height = height;
}
#Override
protected Bitmap doInBackground(Void... params) {
try {
InputStream in = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.connect();
in = httpConn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
int scale = 2;
if (o.outHeight > width || o.outWidth > height) {
scale = 2 ^ (int) Math.ceil(Math.log(width
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5));
}
if (scale <= 1 && o.outHeight > 150) {
scale = 5;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap b1 = BitmapFactory.decodeStream(in, null, o2);
b1 = Bitmap.createScaledBitmap(b1, width, height, true);
loader.addToCache(urlStr, b1);
publishProgress(b1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
iv.setImageBitmap(values[0]);
}
}
And call this method with your arguments,
new LoadPics(ivUser,imgURL,100,50).execute();
try to replace android:scaleType="fitStart" with this android:scaleType="fitXY"
Edit
in your image view you should set the width of imagView to wrap-content this will take the size of image. If you hard-code the imageView's width (as you have done it by giving the width to 40dp) then this will not look so good in other android mobile devices.
Still if you want to do so then Try to load image of lesser in resolution. if this image is 200X100 in resolution, then try to load the image of 100X50 in your ImageView
If you do android:scaleType="FIT_END", without the FrameLayout, does that put the Subway image near the "Subway" text? I wonder, because you have android:layout_alignParentLeft="true" in there. I'm thinking that the ImageView's original size before the scaling is what is throwing off the layout without a FrameLayout.
It probably doesn't matter too much, but it does take some processing to scale and resize the image for what you want it to do. If it is viable for what you want to do, I'd simply resize the image myself instead of relying on XML. If I wanted to cater to multiple sizes, I would have a couple of different layouts made. This of course may be overkill for your purpose, I do not know.
Extra space came in first image because u set match parent in image container layout. but second u used wrap content in FrameLayout which is image container.
my suggession to do these thing Create linear layout insider relative layout and apply layout_weight propert so ratio will be same in both view.
try to set the scale type to center_inside.

ImageView autoresizing when getting a downloaded drawable

I'm getting my downloaded drawables correctly and they show up correctly. I just want to show the top 144x284dip of the image on my ImageView. Instead, when the images are downloaded the ImageView resizes itself to the width and height of the drawable. I've tried modifying both layoutparams and minimumwidth / minimumheight, to no avail.
Is there anything I can do to force the ImageView to stay at 144x284?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="284dip"
android:layout_height="144dip" >
<ImageView
android:id="#+id/imageViewLogo"
android:layout_width="284dip"
android:layout_height="144dip" />
</LinearLayout>
If I understand you correctly, you want to do two things:
Fix the size of the ImageView to 284dip X 144dip.
Show only the top left portion of the image, unscaled.
Doing the second part will require you to use "matrix" scale type and set scale to 1.0 and transform factor to 0.0.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="284dip"
android:layout_height="144dip"
android:scaleType="matrix"
android:src="#drawable/ic_launcher" />
</LinearLayout>
By default, scale factor is 1 and translation is 0. So, you don't have to do anything else. If you do wish a different scaling and translation, you could write code like this.
void showImage(Bitmap bm) {
float scaleFactor = ...;
float transform = ...;
imageView.setImageBitmap(bm);
final Matrix matrix = new Matrix();
matrix.setScale(scaleFactor, scaleFactor);
matrix.setTranslate(transform, transform);
imageView.setImageMatrix(matrix);
}
Ok, I solved it.
I just did this:
Bitmap newBitmap = Bitmap.createBitmap(bm, 0, 0, 144, 284);
Then set it to the ImageView.

Remove ImageView auto-resizing

I want to put and ImageView with a large Y margin on my screen device, which would imply that part of the image would be out of screen, and then that the image would be cropped.
The problem is that Android is scaling the image all the time, so that it fits inside the screen, but I don't want that, I want the image to be cropped.
How can I force the ImageView to be cropped and not resized?
P.S. I tried all the possible ScaleType properties and none of them worked for me!
Code :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:background="#drawable/my_image"
android:scaleType="centerCrop"
/>
</RelativeLayout>
Try replacing android:background with android:src.
First problem with your code is that you used:
android:background="#drawable/my_image"
instead of:
android:src="#drawable/my_image"
(with background none of the scaleType options work).
Now if this still doesn't help, you probably have to use scaleType="matrix" and then simply create a matrix that will do the required job. For example, let's assume that you want to:
keep the ratio of your image
scale the image so that the width parameter will equal X (for example: X can be the width of the screen)
make the top of the image visible (so crop the bottom of the image) - I'm assuming this is why centerCrop might not work for you
Here's the code:
ImageView imgView = (ImageView)findViewById(R.id.my_image_view);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.my_image);
Matrix matrix = new Matrix();
// Let's assume X = 400
float scale = ((float) 400) / bitmap.getWidth();
matrix.setScale(scale, scale);
imgView.setImageMatrix(matrix);
And remember to make the necessary changes in the xml file.

Wrong ImageView dimensions

Edit: partial answer
If both dimensions are set in the xml, it behaves as expected, for example
android:layout_width="250dp"
android:layout_height="250dp"
if one is left to wrap_content, it doesn't.
Original Post
Here is my layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:id="#+id/board"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/board" />
</LinearLayout>
Why does the image I see on screen have the correct dimensions (screen height x screen height because it is a square bitmap and I set match_parent for height), BUT if I call ImageView.getWidth() and ImageView.getHeight() it gives me the screen dimensions?
Best regards
This is happening because of the reason I have provided in your earlier question here
https://stackoverflow.com/a/10183799/1244489
When you call getWidth() and getHeight(), it returns the size of your ImageView which in your case if you observe is the fullscreen size. Your source Image has been shrunk to fit the screen maintaining its aspect ratio but the ImageView isn't shrunk. To shrink it to the Image size, you need to provide the parameter
android:adjustViewBounds="true"
in your ImageView.
Found the answer here:
Fit image into ImageView, keep aspect ratio and then resize ImageView to image dimensions?
Here's the root of the problem: the ImageView doesn't size itself to the image dimensions, so we have to size it ourselves:
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageView.getLayoutParams();
params.width = width;
params.height = height;
imageView.setLayoutParams(params);
Because getWidth() and getHeight() are called from the View hierarchy which are screen dimensions. In fact, if the image was scaled using ImageView's scaletypes like fitCenter, the dimensions you get won't match the image at all. They will remain the pixel width and pixel height of the entire view and not just what was taken up by the image.

Categories

Resources