Resizing a bitmap to a fixed value but without changing the aspect ratio

后端 未结 5 1519
清歌不尽
清歌不尽 2021-02-02 16:41

I\'m looking for a solution for the following problem: how to change the size of a Bitmapto a fixed size (for example 512x128). The aspect ratio of the bitmap conte

相关标签:
5条回答
  • 2021-02-02 17:17

    https://developer.android.com/reference/android/graphics/Bitmap.html#createScaledBitmap(android.graphics.Bitmap, int, int, boolean)

    and make sure that both the dstWidth and dstHeight are obtained from src.getWidth()*scale and src.getHeight()*scale, where scale is a value that you need to determine to make sure the scaled bitmap fits inside 512x128.

    0 讨论(0)
  • 2021-02-02 17:24

    Try this, calculate the ratio and then rescale.

    private Bitmap scaleBitmap(Bitmap bm) {
        int width = bm.getWidth();
        int height = bm.getHeight();
    
        Log.v("Pictures", "Width and height are " + width + "--" + height);
    
        if (width > height) {
            // landscape
            float ratio = (float) width / maxWidth;
            width = maxWidth;
            height = (int)(height / ratio);
        } else if (height > width) {
            // portrait
            float ratio = (float) height / maxHeight;
            height = maxHeight;
            width = (int)(width / ratio);
        } else {
            // square
            height = maxHeight;
            width = maxWidth;
        }
    
        Log.v("Pictures", "after scaling Width and height are " + width + "--" + height);
    
        bm = Bitmap.createScaledBitmap(bm, width, height, true);
        return bm;
    }
    
    0 讨论(0)
  • 2021-02-02 17:28

    The answer by Coen Damen doesn't always respect Max Height and Max Width. Here's an answer that does:

     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 > 1) {
                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)
  • 2021-02-02 17:29

    I think @Coen's answer is not right solution for this question. I also needed a method like this but I wanted to square image.

    Here is my solution for square image;

    public static Bitmap resizeBitmapImageForFitSquare(Bitmap image, int maxResolution) {
    
        if (maxResolution <= 0)
            return image;
    
        int width = image.getWidth();
        int height = image.getHeight();
        float ratio = (width >= height) ? (float)maxResolution/width :(float)maxResolution/height;
    
        int finalWidth = (int) ((float)width * ratio);
        int finalHeight = (int) ((float)height * ratio);
    
        image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
    
        if (image.getWidth() == image.getHeight())
            return image;
        else {
            //fit height and width
            int left = 0;
            int top = 0;
    
            if(image.getWidth() != maxResolution)
                left = (maxResolution - image.getWidth()) / 2;
    
            if(image.getHeight() != maxResolution)
                top = (maxResolution - image.getHeight()) / 2;
    
            Bitmap bitmap = Bitmap.createBitmap(maxResolution, maxResolution, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            canvas.drawBitmap(image, left, top, null);
            canvas.save();
            canvas.restore();
    
            return  bitmap;
        }
    }
    
    0 讨论(0)
  • 2021-02-02 17:32

    I have stumbled upon the same problem a number of times in my projects and each time due to lack of time (and laziness) I would be satisfied with a less than optimum solution. But recently I found some time to crack down this particular issue. Here is my solution and I hope it helps someone down the line...

    Bitmap scaleDownLargeImageWithAspectRatio(Bitmap image)
                {
                    int imaheVerticalAspectRatio,imageHorizontalAspectRatio;
                    float bestFitScalingFactor=0;
                    float percesionValue=(float) 0.2;
    
                    //getAspect Ratio of Image
                    int imageHeight=(int) (Math.ceil((double) image.getHeight()/100)*100);
                    int imageWidth=(int) (Math.ceil((double) image.getWidth()/100)*100);
                    int GCD=BigInteger.valueOf(imageHeight).gcd(BigInteger.valueOf(imageWidth)).intValue();
                    imaheVerticalAspectRatio=imageHeight/GCD;
                    imageHorizontalAspectRatio=imageWidth/GCD;
                    Log.i("scaleDownLargeImageWIthAspectRatio","Image Dimensions(W:H): "+imageWidth+":"+imageHeight);
                    Log.i("scaleDownLargeImageWIthAspectRatio","Image AspectRatio(W:H): "+imageHorizontalAspectRatio+":"+imaheVerticalAspectRatio);
    
                    //getContainer Dimensions
                    int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
                    int displayHeight = getWindowManager().getDefaultDisplay().getHeight();
                   //I wanted to show the image to fit the entire device, as a best case. So my ccontainer dimensions were displayWidth & displayHeight. For your case, you will need to fetch container dimensions at run time or you can pass static values to these two parameters 
    
                    int leftMargin = 0;
                    int rightMargin = 0;
                    int topMargin = 0;
                    int bottomMargin = 0;
                    int containerWidth = displayWidth - (leftMargin + rightMargin);
                    int containerHeight = displayHeight - (topMargin + bottomMargin);
                    Log.i("scaleDownLargeImageWIthAspectRatio","Container dimensions(W:H): "+containerWidth+":"+containerHeight);
    
                    //iterate to get bestFitScaleFactor per constraints
                    while((imageHorizontalAspectRatio*bestFitScalingFactor <= containerWidth) && 
                            (imaheVerticalAspectRatio*bestFitScalingFactor<= containerHeight))
                    {
                        bestFitScalingFactor+=percesionValue;
                    }
    
                    //return bestFit bitmap
                    int bestFitHeight=(int) (imaheVerticalAspectRatio*bestFitScalingFactor);
                    int bestFitWidth=(int) (imageHorizontalAspectRatio*bestFitScalingFactor);
                    Log.i("scaleDownLargeImageWIthAspectRatio","bestFitScalingFactor: "+bestFitScalingFactor);
                    Log.i("scaleDownLargeImageWIthAspectRatio","bestFitOutPutDimesions(W:H): "+bestFitWidth+":"+bestFitHeight);
                    image=Bitmap.createScaledBitmap(image, bestFitWidth,bestFitHeight, true);
    
                    //Position the bitmap centre of the container
                    int leftPadding=(containerWidth-image.getWidth())/2;
                    int topPadding=(containerHeight-image.getHeight())/2;
                    Bitmap backDrop=Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.RGB_565);
                    Canvas can = new Canvas(backDrop);
                    can.drawBitmap(image, leftPadding, topPadding, null);
    
                    return backDrop;
                }
    
    0 讨论(0)
提交回复
热议问题