Search code examples
javaswingbufferedimage

Scaling and drawing a BufferedImage


I have a customized JPanel with an @Override on the paintComponent method which takes an BufferedImage from a member variable and draws it. It works fine until I try to scale the image. I understand from reading that there are two different approaches. One is to use Image.getScaledInstance and the other is to create a Graphics2D with the dimensions of the scaled image. However, when I try to use either of these methods, I either get a completely white rectangle or I get nothing. I am not sure what I am doing wrong. Code for the overridden method is below. Any advice would be appreciated. I am sure this is trivial but I can't see the issue.

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if (img != null) {
        int imageWidth = img.getWidth();
        int imageHeight = img.getHeight();
        int panelWidth = getWidth();
        int panelHeight = getHeight();

        if(imageWidth > panelWidth || imageHeight > panelHeight){
            double aspectRatio = (double)imageWidth / (double)imageHeight;
            int newWidth, newHeight;

            // rescale the height then change the width to pre
            if(imageWidth > panelWidth){
                double widthScaleFactor = (double)panelWidth / (double)imageWidth;
                newWidth = (int)(widthScaleFactor * imageWidth);
                newHeight = (int)(widthScaleFactor * imageWidth / aspectRatio);
            }else{
                double heightScaleFactor = (double)panelHeight / (double)imageHeight;
                newHeight = (int)(heightScaleFactor * imageHeight);
                newWidth = (int)(heightScaleFactor * imageHeight * aspectRatio);
            }

            //BufferedImage scaledImage = (BufferedImage)img.getScaledInstance(newWidth, newHeight, BufferedImage.SCALE_DEFAULT);
            BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, img.getType());
            int x = (panelWidth - newWidth) / 2;
            int y = (panelHeight - newHeight) / 2;

            //Graphics2D g2d = (Graphics2D) g.create();
            Graphics2D g2d = scaledImage.createGraphics();
            //g2d.drawImage(scaledImage, x, y, this);
            g2d.drawImage(img, 0, 0, newWidth, newHeight, null);
            g2d.dispose();
        }else{
            int x = (getWidth() - img.getWidth()) / 2;
            int y = (getHeight() - img.getHeight()) / 2;

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(img, x, y, this);
            g2d.dispose();
        }
    } 

Solution

  • Not sure whether it helps, because you havn't posted a SSCCE, but probably this will work better than your code.

    Image scaledImage = img.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
    int x = (panelWidth - newWidth) / 2;
    int y = (panelHeight - newHeight) / 2;
    g.drawImage(scaledImage, x, y, this);