Android: How to find scale ratio of background image - android

OK, so I have an image that I am using in an ImageView to fill the screen. I am keeping the aspect ratio by using scaletype="centerCrop", as seen here:
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/full_bg" />
In code, how do I go about finding the scale ratio, or scale factor, that resulted from the original image to the scaled image? I need to know so I can apply this same ratio to a button positioned strategically on top of the background. This is what I have tried to get the scale ratio:
ImageView view = (ImageView) findViewById(R.id.imageView1);
Log.i("Test", "x scale = " + Float.toString(view.getScaleX()));
This returns a 1.0 (unscaled) which isn't what I'm looking for. I also tried getting the dimensions of the scaled Bitmap instead of the ImageView, which also gives me the original image size (540px):
ImageView view = (ImageView) findViewById(R.id.imageView1);
Drawable drawing = view.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
Log.i("Test", "width = " + Integer.toString(bitmap.getWidth()));
Am I approaching this all wrong? I can't find anything to help me figure this out. Any help would be much appreciated!

Try this: I got this to change the image size depending on the size of the screen, but this could be easily changed by changing
int width = metrics.widthPixels;
to be
int width = bitmap.getWidth();
or whatever you want it to be scaled to. Note width is the size you're going to.
public static void changeImageSize(ImageView object, Context context){
DisplayMetrics metrics = new DisplayMetrics();
((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
BitmapDrawable bmap = (BitmapDrawable) object.getDrawable();
RelativeLayout.LayoutParams layout = (LayoutParams) object.getLayoutParams();
float bmapWidth = bmap.getBitmap().getWidth();
float bmapHeight = bmap.getBitmap().getHeight();
int newBmapWidth = (int) (bmapWidth*width/480);
int newBmapHeight = (int) (bmapHeight*height/800);
layout.width = newBmapWidth;
layout.height = newBmapHeight;
object.setLayoutParams(layout);
}

Related

How to scale imageview image to specific size?

I created an imageview image, but I want to scale it to be no greater than a fifth of the width and a sixth of the height of the android device's screen size.
Here I get the width and height of the screen:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
here I create my imageview:
ImageView imageView = new ImageView(this);
imageView.setImageResource(icons[0]);
and here I try to scale my imageview:
imageView.getDrawable().setBounds(0, 0, width/5, height/6);
This last part is the stickler. After typing this in I get no errors and my program runs normally - but the image is not scaled. Basically that last line of code seems to have no effect and I have no idea why, any pointers?
Rest of my code:
imageView.setAdjustViewBounds(true);
int mh = imageView.getDrawable().getIntrinsicHeight();
int mw = imageView.getDrawable().getIntrinsicWidth();
imageView.setX(width/2 - Math.round(width/5));
imageView.setY(height/2 - Math.round(height/6) - mActionBarSize);
relativeLayout.addView(imageView);
setContentView(relativeLayout);
do this :
imageView.getLayoutParams().height = (int) Math.round(height/6);
imageView.getLayoutParams().width = (int) Math.round(width/5);
imageView.requestLayout(); // If you're setting the height/width after the layout has already been 'laid out'
see this link to learn more about requestLayout():
Call this when something has changed which has invalidated the layout of this view. This will schedule a layout pass of the view tree.
But ususally the view is calling it automatically, you don't have to care about that... (So for me I use it to force the view to do what I want to do)
Use this
ImageView imgView = (ImageView) findViewById(R.id.pageImage);
imgView.getLayoutParams().height = 100;
imgView.getLayoutParams().width = 100;

Android image scale type to fit width and scaleY = scaleX

I have a layout with a background image. The image width should be the same as the screen width (match_parent). But it's ugly, the OS don't stretch the picture in height.
I heard about ImageView scaleType, so I have the background image in an ImageView instead of a layout background, but I can't config to be what I want.
How can I set to the layout or ImageView to scale the image (in width) to fit the width of the screen AND scale the height with the same scale?
I want the second screen in the picture:
UPDATE:
I'm trying from code, but I get 0 width + I can't believe this can't be done from xml with an ImageView.
Drawable imageDrawable = getResources().getDrawable(imageResource);
contentContainer.setBackgroundDrawable(imageDrawable);
Rect rect = imageDrawable.getBounds();
int originalWidth = rect.width();
int originalHeight = rect.height();
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = originalHeight * (width/originalWidth);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
contentContainer.setLayoutParams(layoutParams);
contentContainer.post(new Runnable() {
#Override
public void run() {
contentContainer.setScaleY(contentContainer.getScaleX());
Rect rect = contentContainer.getBackground().getBounds();
int originalWidth = rect.width();
int originalHeight = rect.height();
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = originalHeight * (width/originalWidth);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
contentContainer.setLayoutParams(layoutParams);
}
}
Use FrameLayout as parent and then add imageview as child.
Give the width match_parent and height fill_parent to the imageView and another ways is apply the android:layout_weight attribute try this may be it's work.
you can do this at runtime by measuring the width of the device like this:--
super.onCreate(savedInstanceState);
setContentView(<layout-resoure-id);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int imageSize = 0;
if (width > height)
imageSize = height;
else
imageSize = width;
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.getLayoutParams().width = imageSize;
imageView.getLayoutParams().height = imageSize;
imageView.setImageResource(R.drawable.pattu);
your xml:--
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY"/>
</LinearLayout>
Enjoy...!
Have you tried playing with scaleType in you layout file?
<ImageView
...
android:scaleType="fitStart"
/>
This should scale your image to fit at the top of your layout, stretching or shrinking if necessary. Haven't had a chance to test (and I can't remember the height/width settings--sorry!), but this could be a solution.
ImageView imageView = (ImageView) findViewById(R.id.your_image_id);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int width = displayMetrics.widthPixels;
int height = displayMetrics.heightPixels;
int imageSize = height>width?width:height;
your configurations go here !
imageView.getLayoutParams().width = imageSize;
imageView.getLayoutParams().height = imageSize + (/* additional height logic*/);
you should put the imageView scaletype as fitXY and do this to stretch the image like the way you want!
<ImageView
...
android:scaleType="fitXY"
/>

Android Programming: How to maintain image size on different displays?

e.g. I want a given Bitmap (100x200px) to always have the following size:
height = 1/10 of the screens height
length = 1/20 of the screens length,
no matter how large the screen is and what resolution it has. How can I do this without creating versions of my bitmap for each of the drawable folders (I've seen examples where all the pictures where only stored in the "drawable" folder, so there must be away without creating 4 instances of each picture used)?
Thanks for the help!
Load your bitmap into an ImageView and set the ScaleType of the ImageView to 'FIT_XY' and it will scale your image to whatever size your ImageView is. You can set the ImageView size to be relative to your screen size by getting the screen dimensions from the WindowManager
For example:-
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
float newWidth = 0.05f * screenWidth;
float newHeight = 0.10f * screenHeight;
imageview.setScaleType( ImageView.ScaleType.FIT_XY );
imageview.setLayoutParams(new LinearLayout.LayoutParams( (int)newWidth, (int)newHeight ));
final int width = getWindowManager().getDefaultDisplay().getWidth();
final int height = getWindowManager().getDefaultDisplay().getHeight();
then use bitmapfactory to scale the image

Aligning a view to an ImageView in different resolutions

The problem with properly handling multiple screen sizes on Android has been talked all over thousands of times. However I couldn't find a solution to m problem. In a nutshell I need to align my custom progress bar over an imageView. I've got 3 set of drawables for the imageView - ldpi(240x400), mdpi(320x480), hdpi(480x800). I align my custom view in Java with the following code:
//get screen density
float density = getBaseContext().getResources().getDisplayMetrics().density;
//set the progress bar position according to screen density
if ( density == 1.0f)
{
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)(height/13.94), (int)(height/13.94));
params.setMargins((int)(width/2.30), 0, 0, (int)(height/2.75));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}else if ( density == 1.5f ){
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)Math.round(height/14.13), (int)Math.round(height/14.13));
params.setMargins((int)Math.round( width/2.27), 0, 0, (int)Math.round(height/2.91));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}else if ( density == 0.75f ){
ImageView micImage = ((ImageView) findViewById(R.id.imageViewClk));
Drawable drawing = micImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
LayoutParams params = new LayoutParams((int)(height/14.88), (int)(height/14.88));
params.setMargins((int)(width/2.27), 0, 0, (int)(height/2.69));
params.addRule(RelativeLayout.ALIGN_LEFT,R.id.imageViewClk);
params.addRule(RelativeLayout.ALIGN_BOTTOM,R.id.imageViewClk);
myCustomTwistedProgressBar.setLayoutParams(params);
}
Everything worked fined on different screen sizes however when I tried to check on 480x854 resolution the vertical alignment of the custom view was incorrect. Checked with 480x800 on the same screen size and it again works. I than went for a big jump and checked in GalaxyTab and the horizontal and vertical alignments were wrong. Now my first though was that the bitmap width and height were the one of the image not the actual resized imageview. So I spent a lot of time on trying to get the real size of the imageview and even went for viewTreeObserver but the results were all the same - the correct, unchanged (unscaled?) bitmap size. So being positive that the problem is not here I couldn't get through further. Does anyone have an idea why the alignment is not working correctly?
PS: as for the image view in layout xml file I have 2 configurations for long and notlong but this image has the same description in both:
<ImageView
android:src="#drawable/cloking"
android:id="#+id/imageViewClk"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="#+id/imageViewProcess"
android:adjustViewBounds="true"
android:cropToPadding="false"
android:layout_marginTop="60dp"
android:scaleType="fitXY">
</ImageView>
Android will scale the image but it will maintain aspect ratio for the image. You can't control aspect ratio with layout settings (as far as I know). I would solve that problem by choosing few screen ratios that I want to support and making few more resources (images that would have aspect ratios that you support). Code would look like this:
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
ImageView image = (ImageView) findViewById(R.id.imageViewClk);
if(width/height == aspectRatio1)
{
image.setImageResource(R.id.imageAspect1);
} else if( width/height == aspectRatio2...

Android Scale Image to largest size

Hi i'm working on an application that will be loading images and i'm looking to scale each image to it's largest possible size for instance if the image is a landscape image (if width is larger than height) i would like to stretch the width to fill the width of the phone and scale height to keep it's aspect ratio. If the height is larger than the width i.e. a portrait image the image should be scaled to fit the height of the phone and width should then adjust to keep the aspect ratio i've had a bit of trouble getting this to work here's what i've done so far though any help would be greatly appreciated.
final ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setBackgroundResource(android.R.color.black);
//TODO need to get actual size of drawable not view size which is 0
ViewTreeObserver vto = i.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
int w = i.getMeasuredWidth();
int h = i.getMeasuredHeight();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
if(w <= h){
//TODO need to think about landscape
h = height - convertDpToPixel(50, context);
w = w*(width);
}else{
h = h*(height);
w = width;
}
//TODO set imageview to w and h
return true;
}
});
for get Display width , height
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;
For Resize Imageview
ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.sc01);
Bitmap resizedbitmap=Bitmap.createScaledBitmap(bmp, width, height, true);
img.setImageBitmap(resizedbitmap);
Increase either the height or the width to their maximum, depending on which is already greater.
Now, let's say you're working with a landscape image:
You've already expanded the width to it's maximum size, the display's width
The side you expanded is the width of the image, so assuming the display width = width and the image's width = w:
width / w = r
So r would be the ratio between the display width and the image width. Now you need to use this to increase your height.
Simply multiply the height by the ratio, and set the image's new height to the resulting number.
If you end up with a portait image... well, I think you'll be able to figure it out. It's pretty much the same thing.
After all that, I think it would just be a matter of positioning the image in the center of the screen.

Categories

Resources