Scale image keeping its aspect ratio in background drawable - android

How do I make a background image fit the view but keep its aspect ratio when using <bitmap /> as a background drawable XML?
None of <bitmap>'s android:gravity values gives the desired effect.

It is impossible to achieve manipulating background attribute within xml-files only. There are two options:
You cut/scale the bitmap programmatically with
Bitmap.createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,
boolean filter) and set it as some View's background.
You use ImageView instead of background placing it as the first layout's element and specify android:scaleType attribute for it:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/backgrnd"
android:scaleType="centerCrop" />
...
rest layout components here
...
</RelativeLayout>

There is an easy way to do this from the drawable:
your_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#color/bg_color"/>
<item>
<bitmap
android:gravity="center|bottom|clip_vertical"
android:src="#drawable/your_image" />
</item>
</layer-list>
The only downside is that if there is not enough space, your image won't be fully shown, but it will be clipped, I couldn't find an way to do this directly from a drawable. But from the tests I did it works pretty well, and it doesn't clip that much of the image. You could play more with the gravity options.
Another way will be to just create an layout, where you will use an ImageView and set the scaleType to fitCenter.
Hope this information helps you achieve what you want.

I wanted to do something similar in my custom Drawable class.
Here are the important pieces:
public class CustomBackgroundDrawable extends Drawable
{
private Rect mTempRect = new Rect();
private Paint mBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
...
public void draw(#NonNull Canvas canvas)
{
Rect bounds = getBounds();
if (mBitmap != null ) {
if (mScaleType == ScaleType.SCALE_FILL) {
//bitmap scales to fill the whole bounds area (bitmap can be cropped)
if (bounds.height() > 0 && bounds.height() > 0) {
float scale = Math.min(mBitmap.getWidth()/(float)bounds.width(), mBitmap.getHeight()/(float)bounds.height());
float bitmapVisibleWidth = scale * bounds.width();
float bitmapVisibleHeight = scale * bounds.height();
mTempRect.set((int)(mBitmap.getWidth()-bitmapVisibleWidth)/2, 0, (int)(bitmapVisibleWidth+mBitmap.getWidth())/2, (int)bitmapVisibleHeight);
canvas.drawBitmap(mBitmap, mTempRect, bounds, mBitmapPaint);
}
} else if (mScaleType == ScaleType.SCALE_FIT) {
//bitmap scales to fit in bounds area
if (bounds.height() > 0 && bounds.height() > 0) {
float scale = Math.min((float)bounds.width()/mBitmap.getWidth(), (float)bounds.height()/mBitmap.getHeight());
float bitmapScaledWidth = scale * mBitmap.getWidth();
float bitmapScaledHeight = scale * mBitmap.getHeight();
int centerPadding = (int)(bounds.width()-bitmapScaledWidth)/2;
mTempRect.set(bounds.left + centerPadding, bounds.top, bounds.right - centerPadding, bounds.top+(int)bitmapScaledHeight);
canvas.drawBitmap(mBitmap, null, mTempRect, mBitmapPaint);
}
}
}
}
With this approach you are flexible to apply any scale logic that you need

Another approach would be to create patch 9 images of your regular image and have it stretch scale the way you want it to.
You could have it center the content by putting 9-patch-dots in the corners that will preserve your ratio obviously (assuming the outer most edge of your image is repeatable/transparent).
Hopefully you get the idea.

If your bitmap is wider than it is tall, use android:gravity="fill_vertical". Otherwise, use android:gravity="fill_horizontal". This has a similar effect as using android:scaleType="centerCrop" on an ImageView.
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_vertical"
android:src="#drawable/image" />
If you support multiple orientations, you can create one bitmap XML file in the drawable-port folder and the other in the drawable-land folder.

Using the method described by a.ch worked great for me except I used this scale type which worked much better for what I needed:
android:scaleType="centerCrop"
Here is a full list of available scale types:
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html

Try using InsetDrawable (worked well for me).
Just give this your drawable, and insets (or padding) you want from either of the four sides.
InsetDrawable insetDrawable = new InsetDrawable(drawable, insetLeft, insetTop, insetRight, insetBottom);
It is specifically used for setting background drawable, of size smaller or than the View.
See Here :
https://developer.android.com/reference/android/graphics/drawable/InsetDrawable.html

Old question, but none of the other answers worked for me. This xml code did however:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:scaleType="centerCrop"
android:src="#drawable/background_image"/>
</RelativeLayout>

In order to fit the image to the available space (or if you have set width and height in dp), I have tried the following approach, also if the image is not too wide.
Here I have set same width and height for square images [or you can wrap_content on both].
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/background_image"/>
</RelativeLayout>
adjust view bounds and scale type center fit does the trick.

Related

CardView shadow not rendered when converted to bitmap

THE PROBLEM
I'm try to save a view group (which has a CardView as one of its childern) as a PNG file. To achieve this,
I inflate the view group and populate the views with required information
Load an image to an image view via Glide
Add a ViewTreeObserver.OnGlobalLayoutListener to the ViewTreeObserver of the image view and pass the entire (parent) view that is going to be shared to a method that converts the view to a bitmap when image view's bottom is greater than zero (image view's height attribute is set to wrap_content, thus its bottom will be zero until image is loaded).
By doing this, I'm able to convert the view to a bitmap, however, with one caveat: the CardView's show is not rendered on the bitmap.
FAILED ATTEMPTS
So far I've tried:
Switching between layerType attribute from "software" to "hardware".
Setting on and off cardUseCompatPadding attribute of the CardView.
Tried setting the image drawable without using Glide.
Tried without loading an image drawable at all.
THE CODE
Here are code snippets that might help you guys identify the problem:
The method used to convert a view to a bitmap
public static Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(b);
//Get the view's background
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return b;
}
XML layout file of the view that's being inflated and passed to the getBitmapFromView() above.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp">
<com.devspark.robototextview.widget.RobotoTextView
android:id="#+id/title"
style="#style/text_subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginBottom="#dimen/lessons_horizontal_margin_narrow"
android:layout_marginLeft="#dimen/lessons_horizontal_margin_narrow"
android:layout_marginRight="#dimen/lessons_horizontal_margin_narrow"
android:layout_marginTop="#dimen/lessons_horizontal_margin_narrow"
android:gravity="left"
app:typeface="roboto_medium" />
<com.devspark.robototextview.widget.RobotoTextView
android:id="#+id/text"
style="#style/text_subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/lessons_horizontal_margin_narrow"
android:layout_marginRight="#dimen/lessons_horizontal_margin_narrow"
android:gravity="left"
android:textColor="#color/text"
app:typeface="roboto_regular" />
<android.support.v7.widget.CardView
android:id="#+id/image_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/lessons_horizontal_margin_narrow"
app:cardCornerRadius="#dimen/lessons_image_card_corner_radius"
app:cardElevation="3dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.makeramen.roundedimageview.RoundedImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#null"
app:riv_corner_radius_top_left="#dimen/lessons_image_card_corner_radius"
app:riv_corner_radius_top_right="#dimen/lessons_image_card_corner_radius" />
<com.devspark.robototextview.widget.RobotoTextView
android:id="#+id/caption"
style="#style/text_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/lessons_image_card_caption_margin"
android:gravity="left"
app:typeface="roboto_condensed_regular" />
</LinearLayout>
</android.support.v7.widget.CardView>
<!-- Some other views that aren't particularly interesting -->
</LinearLayout>
just change cardview to view, and set
android:background="#android:drawable/dialog_holo_light_frame"
ofcause you need to deal the padding yourself
As #galex said - shadows are not drawn on views only by calling measure and layout.
So we can't use the elevation. Also we can't use the drawable shadow, because then we get sharp angles and straight sides.
Solution: use the png 9-path resizable drawable. For this we can use this beautiful tool: Android shadow generator
Create 9-path files for all of mdpi, hdpi, xhdpi, xxhdpi and xxxhdpi.
Put all of your png`s to res/drawables folder.
Now we can use this drawable like background for view where we want to see shadow.
Note that for different densities, you must change following parameter: height and width of the view, shadow offsets (x and y), blur, round corners radius and paddings.
Multipliers for diffrent densities:
LDPI - x0.75//practically not used, so you can do without it
MDPI - x1.0// means original size
HDPI - x1.5
XHDPI - x2.0
XXHDPI - x3.0
XXXHDPI - x4.0
For example if you need to create rectangle with 30dp x 100dp and radius = 8dp
list of 9.path images you should generate:
30х100px, rad = 8
45х150px, rad = 12
60х200px, rad = 16
90х300px, rad = 24
120х400px, rad = 32
I have a same problem. So after searching, I founded this. Hope this help
https://medium.com/#ArmanSo/take-control-of-views-shadow-android-c6b35ba573e9

Android nine patch - allow only a specific area of a background drawable to stretch

How does one go about creating a View that has boundaries with triangular perforations ?
I've been using background drawables to achieve this so far. That works when the dimensions of the View are fixed. Now I have a situation where the height of the View is not constant, so I need to have the height variable on the fly. I can't use a background drawable with a fixed height anymore.
Here is the original background drawable:
And this is what the final View needs to look like:
Another way of looking at the same problem is, can we allow the center of the image to stretch without distorting the boundaries ? If we could do this, we could use the existing drawable as a background.
How can this be achieved ? Has anyone else faced this problem before ? Does the framework have an existing way of dealing with this class of problems ?
Instead of using a normal image, you can generate a nine-patch png.
Use Simple Nine-patch Generator for this.
The trick is the black line on the left side. That tells Android that the png is vertically expandable along this area.
Please see this example:
Save it as a nine-patch, in the format imagename.9.png
You can use a NinePatch image as drawable of that view. To learn how to create a NinePatch image, goto Draw 9-patch
The 9 patch mechanism didn't work to do something similar for my use case, because it requires a stretchable region to be defined in both the horizontal and vertical directions. The 9 patch will only work if the ImageView is able to be constrained to the exact width of the source drawables, to avoid any horizontal stretching.
If the view needs to be allowed to stretch horizontally, maintaining the aspect ratio of the top and bottom boundary portions of the image, while the middle portion is allowed to stretch freely in both directions, a 9 patch won't work for this. I created this layout to accomplish this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/backgroundImage"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:layout_weight="0"
android:src="#drawable/image_top" />
<ImageView
android:id="#+id/imageMiddle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:layout_weight="1"
android:background="#drawable/image_middle" />
<ImageView
android:id="#+id/imageBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:layout_weight="0"
android:src="#drawable/image_bottom" />
</LinearLayout>
image_top.png
image_middle.png
(Note, this image could be shrunk to as little as 1 pixel high, if the subtle gray gradient on the right isn't necessary.)
image_bottom.png
The key is having android:adjustViewBounds="true" on the boundary images, while the drawables are specified with android:src. Then the middle image specifies the drawable with android:background and resizes to fill the height of the parent layout with android:layout_height="match_parent" and android:layout_weight="1".
android:scaleType="fitXY" was necessary in addition in order to force a final scaling of the images after their view bounds are adjusted to handle any potential tiny pixel differences in alignment on hi-res displays. They are all resized to fill their bounds completely.
You can draw a zigzag path in background of your view
Rect rectZigzag = new Rect();
private Path pathZigzag = new Path();
private Paint paintZigzag;
private void init(){
this.paintZigzag = new Paint();
this.paintZigzag.setColor(zigzagBackgroundColor);
this.paintZigzag.setStyle(Style.FILL);
}
private void drawZigzag() {
float left = rectZigzag.left;
float right = rectZigzag.right;
float top = rectZigzag.top;
float bottom = rectZigzag.bottom;
int width = (int) (right - left);
pathZigzag.moveTo(right, bottom);
pathZigzag.lineTo(right, top);
pathZigzag.lineTo(left, top);
pathZigzag.lineTo(left, bottom);
int h = zigzagHeight;
int seed = 2 * h;
int count = width / seed;
int diff = width - (seed * count);
int sideDiff = diff / 2;
float x = (float) (seed / 2);
float upHeight = bottom - h;
float downHeight = bottom;
for (int i = 0; i < count; i++) {
int startSeed = (i * seed) + sideDiff + (int) left;
int endSeed = startSeed + seed;
if (i == 0) {
startSeed = (int) left + sideDiff;
} else if (i == count - 1) {
endSeed = endSeed + sideDiff;
}
this.pathZigzag.lineTo(startSeed + x, upHeight);
this.pathZigzag.lineTo(endSeed, downHeight);
}
}
refrence

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.

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