Scaled Bitmap maintaining aspect ratio

后端 未结 12 855
-上瘾入骨i
-上瘾入骨i 2020-11-30 23:49

I would like to scale a Bitmap to a runtime dependant width and height, where the aspect ratio is maintained and the Bitmap fills the entire width

相关标签:
12条回答
  • 2020-12-01 00:20
    public static Bitmap scaleBitmap(Bitmap bitmap, int wantedWidth, int wantedHeight) {
        float originalWidth = bitmap.getWidth();
        float originalHeight = bitmap.getHeight();
        Bitmap output = Bitmap.createBitmap(wantedWidth, wantedHeight, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        Matrix m = new Matrix();
    
        float scalex = wantedWidth/originalWidth;
        float scaley = wantedHeight/originalHeight;
        float xTranslation = 0.0f, yTranslation = (wantedHeight - originalHeight * scaley)/2.0f;
    
        m.postTranslate(xTranslation, yTranslation);
        m.preScale(scalex, scaley);
        // m.setScale((float) wantedWidth / bitmap.getWidth(), (float) wantedHeight / bitmap.getHeight());
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        canvas.drawBitmap(bitmap, m, paint);
    
        return output;
    }
    
    0 讨论(0)
  • 2020-12-01 00:25

    here is a method from my Utils class, that does the job:

    public static Bitmap scaleBitmapAndKeepRation(Bitmap targetBmp,int reqHeightInPixels,int reqWidthInPixels)
        {
            Matrix matrix = new Matrix();
            matrix .setRectToRect(new RectF(0, 0, targetBmp.getWidth(), targetBmp.getHeight()), new RectF(0, 0, reqWidthInPixels, reqHeightInPixels), Matrix.ScaleToFit.CENTER);
            Bitmap scaledBitmap = Bitmap.createBitmap(targetBmp, 0, 0, targetBmp.getWidth(), targetBmp.getHeight(), matrix, true);
            return scaledBitmap;
        }
    
    0 讨论(0)
  • 2020-12-01 00:26

    Here I have a tested solution where I create a scaled Bitmap out of a bitmap file:

        int scaleSize =1024;
    
        public Bitmap resizeImageForImageView(Bitmap bitmap) {
            Bitmap resizedBitmap = null;
            int originalWidth = bitmap.getWidth();
            int originalHeight = bitmap.getHeight();
            int newWidth = -1;
            int newHeight = -1;
            float multFactor = -1.0F;
            if(originalHeight > originalWidth) {
                newHeight = scaleSize ;
                multFactor = (float) originalWidth/(float) originalHeight;
                newWidth = (int) (newHeight*multFactor);
            } else if(originalWidth > originalHeight) {
                newWidth = scaleSize ;
                multFactor = (float) originalHeight/ (float)originalWidth;
                newHeight = (int) (newWidth*multFactor);
            } else if(originalHeight == originalWidth) {
                newHeight = scaleSize ;
                newWidth = scaleSize ;
            }
            resizedBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
            return resizedBitmap;
        }
    

    Notice that I need scaled Bitmaps which have a maximum size of 4096x4096 Pixels but the aspect ratio needs to be kept while resizing. If you need other values for width or height just replace the values "4096".

    This is just an addition to the answer of Coen but the problem in his code is the line where he calculates the ratio. Dividing two Integers gives an Integer and if the result is < 1 it will be rounded to 0. So this throws the "divide by zero" exception.

    0 讨论(0)
  • 2020-12-01 00:27

    This will respect maxWidth and maxHeight, which means the resulting bitmap will never have dimensions larger then those:

     private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
        if (maxHeight > 0 && maxWidth > 0) {
            int width = image.getWidth();
            int height = image.getHeight();
            float ratioBitmap = (float) width / (float) height;
            float ratioMax = (float) maxWidth / (float) maxHeight;
    
            int finalWidth = maxWidth;
            int finalHeight = maxHeight;
            if (ratioMax > ratioBitmap) {
                finalWidth = (int) ((float)maxHeight * ratioBitmap);
            } else {
                finalHeight = (int) ((float)maxWidth / ratioBitmap);
            }
            image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
            return image;
        } else {
            return image;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 00:27

    simpler solution : note we set the width to 500 pixels

     public void scaleImageKeepAspectRatio()
        {
            int imageWidth = scaledGalleryBitmap.getWidth();
            int imageHeight = scaledGalleryBitmap.getHeight();
            int newHeight = (imageHeight * 500)/imageWidth;
            scaledGalleryBitmap = Bitmap.createScaledBitmap(scaledGalleryBitmap, 500, newHeight, false);
    
        }
    
    0 讨论(0)
  • 2020-12-01 00:29

    There is simple math involved in rescaling the image, consider the following snippet and follow along, 1. Suppose, you have Imaan image with 720x1280 and you want to to be fit in 420 width, get the percentage of reduction required by given math,

    originalWidth = 720;
    wP = 720/100;
    /*  wP = 7.20 is a percentage value */
    
    1. Now subtract the required width from original width and then multiply the outcome by wP. You will get the percentage of width being reduced.

    difference = originalWidth - 420; dP = difference/wP;

    Here dP will be 41.66, means you are reducing the size 41.66%. So you have to reduce the height by 41.66(dP) to maintain the ration or scale of that image. Calculate the height as given below,

    hP = originalHeight / 100;
    //here height percentage will be 1280/100 = 12.80
    height = originalHeight - ( hp * dP);
    // here 1280 - (12.80 * 41.66) = 746.75
    

    Here is your fitting scale, you can resize image/Bitmap in 420x747. It will return the resized image without losing the ratio/scale.

    Example

    public static Bitmap scaleToFit(Bitmap image, int width, int height, bool isWidthReference) {
        if (isWidthReference) {
            int originalWidth = image.getWidth();
            float wP = width / 100;
            float dP = ( originalWidth - width) / wP;
            int originalHeight = image.getHeight();
            float hP = originalHeight / 100;
            int height = originalHeight - (hP * dP);
            image = Bitmap.createScaledBitmap(image, width, height, true);
        } else {
            int originalHeight = image.getHeight();
            float hP = height / 100;
            float dP = ( originalHeight - height) / hP;
            int originalWidth = image.getWidth();
            float wP = originalWidth / 100;
            int width = originalWidth - (wP * dP);
            image = Bitmap.createScaledBitmap(image, width, height, true);
        }
        return image;
    }
    

    here you are simply scaling the image with reference of height or width parameter to fit into required criteria.

    0 讨论(0)
提交回复
热议问题