package ru.kkey.ui.widget; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.Map; /** * The panel render image with scalling over window size * * @author astarovoyt */ public class AutoResizeImagePanel extends JPanel { private static final long serialVersionUID = 1L; static final Map<RenderingHints.Key, Object> hints = new HashMap<>(); static { hints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED); hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); hints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE); hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED); hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } private final BufferedImage image; private final int imageWidth; private final int imageHeight; private Image prevImage; private int prevWidth = -1; private int prevHeight = -1; public AutoResizeImagePanel(BufferedImage image) { this.imageWidth = image.getWidth(); this.imageHeight = image.getHeight(); this.image = getNewBufferedImage(image); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.addRenderingHints(hints); int w = getWidth(); int h = getHeight(); int iw = getImageWidth(); int ih = getImageHeight(); double xScale = (double) w / iw; double yScale = (double) h / ih; double scale = Math.min(xScale, yScale); int width = scale < 1 ? (int) (scale * iw) : iw; int height = scale < 1 ? (int) (scale * ih) : ih; if (width != prevWidth || height != prevHeight) { prevImage = scaleImage(image, width, height); prevHeight = height; prevWidth = width; } int startX = (w - width) / 2; int startY = (h - height) / 2; g2.drawImage(prevImage, startX, startY, this); } private int getImageHeight() { return imageHeight; } private int getImageWidth() { return imageWidth; } private BufferedImage getNewBufferedImage(BufferedImage image) { GraphicsConfiguration gc = getConfiguration(); BufferedImage newImage = gc.createCompatibleImage(image.getWidth(), image.getHeight(), Transparency.BITMASK); Graphics2D graphics = (Graphics2D) newImage.getGraphics(); graphics.addRenderingHints(hints); graphics.drawImage(image, 0, 0, null); graphics.dispose(); return newImage; } private GraphicsConfiguration getConfiguration() { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice screen = ge.getDefaultScreenDevice(); return screen.getDefaultConfiguration(); } private BufferedImage scaleImage(BufferedImage src, int targetWidth, int targetHeight) { BufferedImage result = new BufferedImage( targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D resultGraphics = result.createGraphics(); resultGraphics.addRenderingHints(hints); resultGraphics.drawImage(src, 0, 0, targetWidth, targetHeight, null); resultGraphics.dispose(); return result; } }