24

I want to know how to scale bitmap to screen height and width?

Can anyone pls tell me how to do this.

Thanks Monali

Monali
  • 1,966
  • 12
  • 39
  • 59
  • What do you have? A layout with an ImageView, or a Bitmap/Drawable and a Canvas? – Kaj Jun 20 '11 at 11:21
  • If the layout is a canvas, does Cordova autoscale the canvas for different screen size, or must we do it ourselves manually? – bouncingHippo Jun 20 '12 at 14:12

5 Answers5

29

Try this to Decode the Bitmap :

Where imagefilepath is the path name of image,it will be in String covert that to File by using

File photos= new File(imageFilePath);

Where photo is the File name of the Image,Now you set your height and width according t your requirements.

public void main(){
    Bitmap bitmap = decodeFile(photo);
    bitmap = Bitmap.createScaledBitmap(bitmap,150, 150, true);
    imageView.setImageBitmap(bitmap);
} 

private Bitmap decodeFile(File f){
    try {
        //decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);              
        //Find the correct scale value. It should be the power of 2.
        final int REQUIRED_SIZE=70;
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale++;
        }

        //decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
        return null;
}
Chad Bingham
  • 32,650
  • 19
  • 86
  • 115
Venky
  • 11,049
  • 5
  • 49
  • 66
  • 5
    This is better than naive implementations and uses less memory. – David Snabel-Caunt Jun 20 '11 at 11:38
  • 1
    There is a slight mistake in the code. It should be `scale*=2;` instead of scale++; – Saqib Jun 08 '13 at 22:24
  • I think I am having the same issue and I guess I have to use LayoutParams? Please help me resolve this issue: http://stackoverflow.com/questions/21420278/how-to-keep-an-image-inside-layout-on-drag – Si8 Jan 29 '14 at 01:59
  • 2
    Instead of doing all this work to calculate the scale for inSampleSize, can't you just do `o2.inSampleSize = (int) (Math.min(width_tmp, height_tmp) / REQUIRED_SIZE);`? According to the documentation on BitmapFactory.Options.inSampleSize, `the decoder uses a final value based on powers of 2, any other value will be rounded down to the nearest power of 2`. So I think it would do most of the work for you. – Tony Wickham Jul 16 '14 at 17:28
15

I had a similar challenge where I wanted to stretch the width to 100% of screen, but keep the width/height ratio intact. So I did this..

Create a ScalableImageView class that extends ImageView:

public class ScalableImageView extends ImageView {
    public boolean isMeasured = true; 

    public ScalableImageView(Context context) {
        super(context);
    }

    public ScalableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScalableImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        try
        {
            Drawable drawable = getDrawable();

            if (drawable == null)
            {
                setMeasuredDimension(0, 0);
            }
            else
            {
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = width * drawable.getIntrinsicHeight() / drawable.getIntrinsicWidth();
                setMeasuredDimension(width, height);
            }
        }
        catch (Exception e)
        {
            isMeasured = false;
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

In the layout XML file, I have a placeholder for the image defined like this:

<ScalableImageView android:id="@+id/image1" 
    android:layout_centerHorizontal="true"
    android:src="@drawable/cam_image_placeholder" 
    android:scaleType="fitCenter" 
    android:layout_gravity="center_horizontal" 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:adjustViewBounds="true"
    android:visibility="invisible" 
    android:layout_marginBottom="6px">
</ScalableImageView>

And then load/set it like this:

ScalableImageView imgView = null;
imgView = (ScalableImageView)findViewById(imgViewResource);
imgView.setImageDrawable(myDrawable);
imgView.setVisibility(ScalableImageView.VISIBLE);
Kon
  • 27,113
  • 11
  • 60
  • 86
  • This was really useful for me figuring out how to scale using only one dimension (Scaling the width or height) and maintaining the correct ratio. Thanks! – steve-gregory Feb 01 '12 at 20:12
  • Glad it's helpful. Enjoy. – Kon Jul 11 '13 at 13:33
  • 3
    This will not work if you are setting a bitmap programmatically. – Nizzy Dec 12 '13 at 20:49
  • Instead you can simply use a Imageview and set the width to match parent and height to wrap content, use scaletype "fitXY" and adjustViewbounds to true. You will get the same desired effect. – AmeyaB Apr 16 '16 at 19:43
  • @AmeyaB Which android version does that work with, because that was one of the first things I tried and it has never worked for me, the way you've described it. – siphr Jun 08 '17 at 21:19
9

You can use Bitmap.createScaledBitmap(), but make sure to use the correct conversion formula when you use it:

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);

In Bitmap.createScaledBitmap() the units for the width and height are "pixels", while you should always set your size in density-independent pixels (dp units) as described here.

So, if you want to show your images maintaining density independence - i.e. your images will occupy the same portion of screen on any device - you need to use a code similar to the following:

Bitmap b = decodeScaledFile(f);

final float scale = mContext.getResources().getDisplayMetrics().density;
int p = (int) (SIZE_DP * scale + 0.5f);

Bitmap b2 = Bitmap.createScaledBitmap(b, p, p, true);
Lorenzo Polidori
  • 10,332
  • 10
  • 51
  • 60
  • @LuxuryMode `SIZE_DP` is the size of the image in Density-independent Pixels - see [here](http://developer.android.com/guide/topics/resources/more-resources.html#Dimension) – Lorenzo Polidori Apr 21 '12 at 19:33
  • 1
    does using createScaledBitmap actually creates a totally new bitmap, so you use memory for 2 bitmaps ? for example, if the first bitmap takes x bytes, will a bitmap that is scaled by 2 take 2*2=4 times plus the original, so in total you use about 4x+x=5x bytes? – android developer May 06 '13 at 22:33
2

first get the screen height and width:
Android: How to get screen dimensions 1: Get screen dimensions in pixels then
have a look at this: Resizing a Bitmap

Community
  • 1
  • 1
0

You can create a scaledBitmap based on this code.

private Bitmap getScaledBitMapBaseOnScreenSize(Bitmap bitmapOriginal){

    Bitmap scaledBitmap=null;
    try {
        DisplayMetrics metrics = new DisplayMetrics();
        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);


        int width = bitmapOriginal.getWidth();
        int height = bitmapOriginal.getHeight();

        float scaleWidth = metrics.scaledDensity;
        float scaleHeight = metrics.scaledDensity;

        // create a matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);

        // recreate the new Bitmap
        scaledBitmap = Bitmap.createBitmap(bitmapOriginal, 0, 0, width, height, matrix, true);
    }
    catch (Exception e){
        e.printStackTrace();
    }
    return scaledBitmap;
}

Method calling & set the scaled image to imageview

 Bitmap scaleBitmap=getScaledBitMapBaseOnScreenSize(originalBitmapImage);
    if(scaleBitmap!=null) {
    imageView.setImageBitmap(scaleBitmap);
    }

My xml code for imageview,

 <ImageView
    android:id="@+id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:scaleType="center"
    />
Ranjithkumar
  • 16,071
  • 12
  • 120
  • 159