Stretch ImageView height and maintaining aspect ratio - android

Is there a way in android to display an ImageView by maintaining it's aspect ratio but increasing the height before doing so.
So for example, I have different images that I store inside an ImageView by maintaining it's aspect ratio:
<ImageView
android:id="#+id/coupon_detail_barcode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
So, let's say the image that comes in is 40dp height and 40dp width. Instead of maintaining that original ratio, I want to stretch the image out first to 42dp height, 40dp width, THEN having it displayed maintaining those new ratios.
I'm assuming there is no way to do it in XML and would have to do it all programmatically.

Get the image as a byte array then:
Bitmap bitmap = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
// Adjust size here.
Bitmap adjustedBitmap = Bitmap.createScaledBitmap(bitmap, 120, 120, false));
// Set adjustedBitmap into ImageView
someImageView.setImageBitmap(adjustedBitmap);

Related

I want to put a bitmap inside imageview keeping aspect ratio

This is my xml code:
<ImageView
android:id="#+id/ColImgPath"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:background="#drawable/border"/>
and this my java code, that it is inside listview:
ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
imageView.setPadding(5, 5, 5, 5);
imageView.setVisibility(View.VISIBLE);
try {
Bitmap bmp = ((Bitmap) MyArrList.get(position).get("ImageThumBitmap"));
int bmpx = bmp.getWidth();
int bmpy = bmp.getHeight();
Log.i("INFO","X: "+bmpx+" Y: "+bmpy);
Bitmap photobitmap1 = Bitmap.createScaledBitmap(bmp, bmpx/2,bmpy/2, true);
imageView.setImageBitmap(photobitmap1);
//imageView.setImageBitmap((Bitmap) MyArrList.get(position).get("ImageThumBitmap"));
} catch (Exception e) {
// When Error
imageView.setImageResource(android.R.drawable.ic_menu_report_image);
}
The problem is that I want to put the bitmap resized into bitmap but the imageview always appears squared.
The size of the bitmap is: X: 4160 Y: 3120 and the screen size is : WIDTH= 1080 HEIGHT= 1776
I want to put the width fill parent and resize the height keeping the aspect ratio. I tried some xml alternatives like `ScaleType.
Someone knows the way to put correctly the bitmap?
Does fitXy not work for the scale type?
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
It's an ImageView so you need to use android:src="#drawable/border" instead of android:background. Also try android:scaleType="fitXY" or cropCenter.
There are different Scale Type Available in Android ImageView
CENTER_INSIDE - used to set Bitmap with keeping bitmap original aspect ratio.
CENTER_CROP - used to set Bitmap in imageview to cover imageview without broken aspect Ratio , rather bitmap set from negative x , y value to cover imageview area.
FIT_XY - used to set whole bitmap into available ImageView height and width means bitmap takes Imageviews Aspect Ratio.
OR
if you want to resize bitmap then take height or width which you want to set and take ratio of height / width if take width or take width/ height if you have next height and multiply repetitive width and height to this ratio .It will change height and width of bitmap but keep Aspect Ratio of original Bitmap .

How to maintain the aspect ratio of the image if imageview first stretch to fill parent

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"/>

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.

How do I display this image in Android?

How do I display an image with the following configuration in Android?
Retain original aspect ratio (the image can be scaled, but not stretched)
Fill the width of the parent
Aligned to the bottom of the parent
The following does not work:
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:layout_alignParentBottom="true"
android:src="#drawable/background" />
Using the above xml the ImageView takes the width of the parent, but the image inside the ImageView does not.
Some points.
If you want to manteint aspect ratio instead of fitCenter you should try centerInside:
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).
Remember that devices using your application might have different screen sizes.
If your background image is something that can be stretched I would recommend you try a NinePatchDrawable

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

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));

Categories

Resources