package eu.crushedpixel.replaymod.utils; import java.awt.*; import java.awt.image.BufferedImage; public class ImageUtils { public static BufferedImage scaleImage(BufferedImage img, Dimension d) { img = scaleByHalf(img, d); img = scaleExact(img, d); return img; } private static BufferedImage scaleByHalf(BufferedImage img, Dimension d) { int w = img.getWidth(); int h = img.getHeight(); float factor = getBinFactor(w, h, d); // make new size w *= factor; h *= factor; BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = scaled.createGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); g.drawImage(img, 0, 0, w, h, null); g.dispose(); return scaled; } private static BufferedImage scaleExact(BufferedImage img, Dimension d) { float factor = getFactor(img.getWidth(), img.getHeight(), d); // create the image int w = (int) (img.getWidth() * factor); int h = (int) (img.getHeight() * factor); BufferedImage scaled = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D g = scaled.createGraphics(); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(img, 0, 0, w, h, null); g.dispose(); return scaled; } static float getBinFactor(int width, int height, Dimension dim) { float factor = 1; float target = getFactor(width, height, dim); if(target <= 1) { while(factor / 2 > target) { factor /= 2; } } else { while(factor * 2 < target) { factor *= 2; } } return factor; } static float getFactor(int width, int height, Dimension dim) { float sx = dim.width / (float) width; float sy = dim.height / (float) height; return Math.min(sx, sy); } public static BufferedImage cropImage(BufferedImage src, Rectangle rect) { return src.getSubimage(rect.x, rect.y, rect.width, rect.height); } }