Search code examples
javaimagescaling

Most efficent way to scale down an image while maintaining aspect ratio?


So I have a field where my image displays and my max height can be 375 and max width is 775. I want it to be as close to as one of these values as possible to get the maximum size while maintaining the aspect ratio This is what I came up with and it actually seems to work pretty well but I am thinking there is a better way I am not thinking of.

    InputStream in = new ByteArrayInputStream(fileData);
    BufferedImage buf = ImageIO.read(in);

    int maxWidth = 775;
    int maxHeight = 375;
    int newWidth;
    int newHeight;
    float height = buf.getHeight();
    float width = buf.getWidth();
    float ratio = (float) 0.0;

    if(height > maxHeight || width > maxWidth)
    {

     if (height > width)
     {
        ratio = (height/width);
     }
     else if(width > height)
         ratio = (width/height);
     while(height > maxHeight || width > maxWidth)
     {
        if (height > width)
         {              
            height -= ratio;
            width -= 1;
         }

         else if(width > height)
         {
                width -= ratio; 
                height -= 1;                                    
         }

    }
    }
    newWidth = (int) width;
    newHeight = (int) height;

    // Call method to scale image to appropriate size
    byte[] newByte = scale(fileData, newWidth, newHeight);

Solution

  • You know that you will use one of the two maxes (if you weren't the image could still be scaled up).

    So it's just a problem of determining which. If this aspect ratio of the image is greater than your max area ratio, then width is your limiting factor, so you set width to max, and determine height from your ratio.

    Same process can be applied for a smaller ratio

    Code looks something like the following

    float maxRatio = maxWidth/maxHeight;
    if(maxRatio > ratio) {
        width = maxWidth;
        height = width / ratio;
    } else {
        height = maxHeight;
        width = height * ratio;
    }