@NotNull public static BufferedImage scale(BufferedImage source,double xScale,double yScale,int rightMargin,int bottomMargin,@Nullable Shape clip){
  int sourceWidth=source.getWidth();
  int sourceHeight=source.getHeight();
  int destWidth=Math.max(1,(int)(xScale * sourceWidth));
  int destHeight=Math.max(1,(int)(yScale * sourceHeight));
  int imageType=source.getType();
  if (imageType == BufferedImage.TYPE_CUSTOM) {
    imageType=BufferedImage.TYPE_INT_ARGB;
  }
  if (xScale > 0.5 && yScale > 0.5) {
    BufferedImage scaled=new BufferedImage(destWidth + rightMargin,destHeight + bottomMargin,imageType);
    Graphics2D g2=scaled.createGraphics();
    g2.setComposite(AlphaComposite.Src);
    g2.setColor(new Color(0,true));
    g2.fillRect(0,0,destWidth + rightMargin,destHeight + bottomMargin);
    if (clip != null) {
      g2.setClip(clip);
    }
    if (xScale == 1 && yScale == 1) {
      g2.drawImage(source,0,0,null);
    }
 else {
      g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
      g2.setRenderingHint(KEY_RENDERING,VALUE_RENDER_QUALITY);
      g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
      g2.drawImage(source,0,0,destWidth,destHeight,0,0,sourceWidth,sourceHeight,null);
    }
    g2.dispose();
    return scaled;
  }
 else {
    int iterations=0;
    int nearestWidth=destWidth;
    int nearestHeight=destHeight;
    while (nearestWidth < sourceWidth / 2) {
      nearestWidth*=2;
      nearestHeight*=2;
      iterations++;
    }
    if (iterations == 0) {
      nearestWidth+=rightMargin;
      nearestHeight+=bottomMargin;
    }
    @SuppressWarnings("UndesirableClassUsage") BufferedImage scaled=new BufferedImage(nearestWidth,nearestHeight,imageType);
    Graphics2D g2=scaled.createGraphics();
    g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
    g2.setRenderingHint(KEY_RENDERING,VALUE_RENDER_QUALITY);
    g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
    g2.drawImage(source,0,0,nearestWidth,nearestHeight,0,0,sourceWidth,sourceHeight,null);
    g2.dispose();
    sourceWidth=nearestWidth;
    sourceHeight=nearestHeight;
    source=scaled;
    for (int iteration=iterations - 1; iteration >= 0; iteration--) {
      int halfWidth=sourceWidth / 2;
      int halfHeight=sourceHeight / 2;
      if (iteration == 0) {
        scaled=new BufferedImage(halfWidth + rightMargin,halfHeight + bottomMargin,imageType);
        g2=scaled.createGraphics();
        if (clip != null) {
          g2.setClip(clip);
        }
      }
 else {
        scaled=new BufferedImage(halfWidth,halfHeight,imageType);
        g2=scaled.createGraphics();
      }
      g2.setRenderingHint(KEY_INTERPOLATION,VALUE_INTERPOLATION_BILINEAR);
      g2.setRenderingHint(KEY_RENDERING,VALUE_RENDER_QUALITY);
      g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
      g2.drawImage(source,0,0,halfWidth,halfHeight,0,0,sourceWidth,sourceHeight,null);
      g2.dispose();
      sourceWidth=halfWidth;
      sourceHeight=halfHeight;
      source=scaled;
      iterations--;
    }
    return scaled;
  }
}

@ NotNull public static BufferedImage scale ( BufferedImage source , double xScale , double yScale , int rightMargin , int bottomMargin , @ Nullable Shape clip ) { int sourceWidth = source . getWidth ( ) ; int sourceHeight = source . getHeight ( ) ; int destWidth = Math . max ( 1 , ( int ) ( xScale * sourceWidth ) ) ; int destHeight = Math . max ( 1 , ( int ) ( yScale * sourceHeight ) ) ; int imageType = source . getType ( ) ; if ( imageType == BufferedImage . TYPE_CUSTOM ) { imageType = BufferedImage . TYPE_INT_ARGB ; } if ( xScale > 0.5 && yScale > 0.5 ) { BufferedImage scaled = new BufferedImage ( destWidth + rightMargin , destHeight + bottomMargin , imageType ) ; Graphics2D g2 = scaled . createGraphics ( ) ; g2 . setComposite ( AlphaComposite . Src ) ; g2 . setColor ( new Color ( 0 , true ) ) ; g2 . fillRect ( 0 , 0 , destWidth + rightMargin , destHeight + bottomMargin ) ; if ( clip != null ) { g2 . setClip ( clip ) ; } if ( xScale == 1 && yScale == 1 ) { g2 . drawImage ( source , 0 , 0 , null ) ; } else { g2 . setRenderingHint ( KEY_INTERPOLATION , VALUE_INTERPOLATION_BILINEAR ) ; g2 . setRenderingHint ( KEY_RENDERING , VALUE_RENDER_QUALITY ) ; g2 . setRenderingHint ( KEY_ANTIALIASING , VALUE_ANTIALIAS_ON ) ; g2 . drawImage ( source , 0 , 0 , destWidth , destHeight , 0 , 0 , sourceWidth , sourceHeight , null ) ; } g2 . dispose ( ) ; return scaled ; } else { int iterations = 0 ; int nearestWidth = destWidth ; int nearestHeight = destHeight ; while ( nearestWidth < sourceWidth / 2 ) { nearestWidth *= 2 ; nearestHeight *= 2 ; iterations ++ ; } if ( iterations == 0 ) { nearestWidth += rightMargin ; nearestHeight += bottomMargin ; } @ SuppressWarnings ( "UndesirableClassUsage" ) BufferedImage scaled = new BufferedImage ( nearestWidth , nearestHeight , imageType ) ; Graphics2D g2 = scaled . createGraphics ( ) ; g2 . setRenderingHint ( KEY_INTERPOLATION , VALUE_INTERPOLATION_BILINEAR ) ; g2 . setRenderingHint ( KEY_RENDERING , VALUE_RENDER_QUALITY ) ; g2 . setRenderingHint ( KEY_ANTIALIASING , VALUE_ANTIALIAS_ON ) ; g2 . drawImage ( source , 0 , 0 , nearestWidth , nearestHeight , 0 , 0 , sourceWidth , sourceHeight , null ) ; g2 . dispose ( ) ; sourceWidth = nearestWidth ; sourceHeight = nearestHeight ; source = scaled ; for ( int iteration = iterations - 1 ; iteration >= 0 ; iteration -- ) { int halfWidth = sourceWidth / 2 ; int halfHeight = sourceHeight / 2 ; if ( iteration == 0 ) { scaled = new BufferedImage ( halfWidth + rightMargin , halfHeight + bottomMargin , imageType ) ; g2 = scaled . createGraphics ( ) ; if ( clip != null ) { g2 . setClip ( clip ) ; } } else { scaled = new BufferedImage ( halfWidth , halfHeight , imageType ) ; g2 = scaled . createGraphics ( ) ; } g2 . setRenderingHint ( KEY_INTERPOLATION , VALUE_INTERPOLATION_BILINEAR ) ; g2 . setRenderingHint ( KEY_RENDERING , VALUE_RENDER_QUALITY ) ; g2 . setRenderingHint ( KEY_ANTIALIASING , VALUE_ANTIALIAS_ON ) ; g2 . drawImage ( source , 0 , 0 , halfWidth , halfHeight , 0 , 0 , sourceWidth , sourceHeight , null ) ; g2 . dispose ( ) ; sourceWidth = halfWidth ; sourceHeight = halfHeight ; source = scaled ; iterations -- ; } return scaled ; } }
resize the given image
