【问题标题】:Fit image into JPanel使图像适合 JPanel
【发布时间】:2021-04-08 12:27:40
【问题描述】:

我正在尝试缩放图像,使其始终适合我的 JPanel。不幸的是,使用这种方法我并不总是收到我想收到的图像。大多数情况下它是缩放的,我宁愿将整个图像缩放。

那是创建图像的类。 600 是 PanelWidth,400 是 PanelHeight。

有什么想法吗?

public class Image extends Component{
    
    private BufferedImage img;
    protected int width;
    protected int height;
    private String path;

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

        double scale = getScale(600,400,img.getWidth(),img.getHeight());
        double xPos = (600 - scale * img.getWidth())/2;
        double yPos = (400 - scale *img.getHeight())/2;
        
        AffineTransform at = AffineTransform.getTranslateInstance(xPos, yPos);
        at.scale(scale, scale);
        g2.drawRenderedImage(img, at);
        System.out.println(scale);
        
    }

    public Image(String path){
        try{
            img = ImageIO.read(new File(path));
        } catch (IOException e) { }
        this.width=img.getWidth();
        this.height=img.getHeight();
        this.path = path;
    }
   
    
    public double getScale(int panelWidth, int panelHeight, int imageWidth, int imageHeight){
        double scale = 1;
        double xScale, yScale;
        
        if(imageWidth > panelWidth || imageHeight > panelHeight){
            xScale = (double)imageWidth/panelWidth;
            yScale = (double)imageHeight/panelHeight;
            scale = Math.max(xScale, yScale);
        }else if(imageWidth < panelWidth && imageHeight < panelHeight){
            xScale = (double)panelWidth/imageWidth;
            yScale = (double)panelHeight/imageHeight;
            scale = Math.max(xScale, yScale);
        }else{
            scale = 1;
        }
        return scale;
    }

【问题讨论】:

    标签: java image swing jpanel


    【解决方案1】:

    JPanel 是一个 Swing 组件,这意味着您正在使用 Swing。

    对于自定义绘画,您应该扩展 JPanelJComponent。大多数人使用 JPanel 是因为它会为您清除组件的背景。

    Swing 组件的自定义绘制是通过覆盖 paintComponent(...) 来完成的

    所以它总是适合我的 JPanel

    定义“适合”?

    假设您正在尝试缩放图像以保留其原始比例,您可以如下所示:

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
    
        double imageWidth = image.getWidth(null);
        double imageHeight = image.getHeight(null);
        double factor = Math.min(getWidth() / imageWidth, getHeight() / imageHeight);
        int width = (int)(image.getWidth(null) * factor);
        int height = (int)(image.getHeight(null) * factor);
        g.drawImage(image, 0, 0, width, height, this);
    }
    

    如果您只是想在面板上调整图像,那么您可以这样做:

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
    
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    }
    

    【讨论】:

    • 谢谢。它似乎工作。我试图缩放图像。它是一个可以加载任何图像的程序,因此它们总是具有不同的尺寸,我希望我的应用程序始终保持相同的尺寸并很好地适应图像,同时保持比例。
    【解决方案2】:

    如果您以正确的顺序执行操作,则不需要使用 float。假设imageWidthimageHeightpanelWidth都是int

    // Calculate the width of the scaled image; if the image is wider than the 
    // panel, use the panel width, otherwise use the image width (i.e. don't upscale)
    
    int scaledWidth = Math.min(imageWidth, panelWidth);
    
    // Given the scaled width, calculate the scaled height
    // Force it to be at least 1 pixel, since if you have an image that's wider than
    // the panel and only 1 pixel tall, this will scale to zero height, which you
    // don't want
    
    int scaledHeight = Math.max(1, imageHeight * scaledWidth / imageWidth); 
    

    以上假设您想要适应宽度,并且如果图像高度超过面板高度,将提供滚动机制。如果您想改为适合高度(以及水平滚动以进行溢出),只需对变量进行必要的更改。

    【讨论】:

      猜你喜欢
      • 2012-05-24
      • 2016-01-01
      • 2013-05-25
      • 2014-05-01
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 2011-10-24
      • 2013-03-24
      相关资源
      最近更新 更多