繁体   English   中英

调整 JLabel 的大小以适应其中包含图像的 JInternalFrame

[英]Resize JLabel to fit JInternalFrame with an image in it

如何使用JLabel在内部框架中调整图像大小?

我尝试了一些在 Inte.net 上找到的代码,例如:

public static BufferedImage resize(Image image, int width, int height) {
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
    Graphics2D g2d = (Graphics2D) bi.createGraphics();
    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
    g2d.drawImage(image, 0, 0, width, height, null);
    g2d.dispose();
    return bi;  

或者

getScaledInstance(l.getWidth(),  -1, Image.SCALE_SMOOTH);

代码的结果

但它只会使图像变小。

有没有办法使用JLabelJInternalFrame调整图像大小? 欢迎任何帮助:)

缩放图像并不简单。 看一眼:

缩放也可能很昂贵,因此您可能希望以某种方式减少尝试次数(因为重新调整大小的 window 将受到大量调整大小事件的轰炸)。

无论您使用的是JFrameJPanel还是JInternalFrame ,总体方法都是相同的。

您需要一些方法来监视大小变化,并需要一些方法来确定何时适合缩放图像。 以下示例使用ComponentListener和非重复 Swing Timer 这使我们能够安排在未来执行的任务,但如果需要可以取消。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    BufferedImage image = ImageIO.read(getClass().getResource("/images/happy.png"));

                    JInternalFrame internalFrame = new JInternalFrame("Test", true, true, true, true);
                    internalFrame.add(new ImagePane(image));
                    internalFrame.pack();
                    internalFrame.setVisible(true);

                    JDesktopPane desktopPane = new JDesktopPane();
                    desktopPane.add(internalFrame);

                    JFrame frame = new JFrame();
                    frame.add(desktopPane);
                    frame.setSize(new Dimension(800, 800));
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class ImagePane extends JPanel {

        private Timer resizeTimer;
        private BufferedImage masterImage;
        private JLabel label;
        private Scaler scaler;

        public ImagePane(BufferedImage masterImage) {
            this.masterImage = masterImage;
            label = new JLabel(new ImageIcon(masterImage));

            scaler = new Scaler(masterImage);
            resizeTimer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setIcon(new ImageIcon(scaler.getScaledInstanceToFill(getSize())));
                }
            });
            resizeTimer.setRepeats(false);
            addComponentListener(new ComponentAdapter() {
                @Override
                public void componentResized(ComponentEvent e) {
                    resizeTimer.restart();
                }
            });
            setLayout(new BorderLayout());
            add(label);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class Scaler {

        private BufferedImage master;
        private Dimension masterSize;

        private Map<RenderingHints.Key, Object> renderingHints = new HashMap<>();

        public Scaler(BufferedImage master) {
            this.master = master;
            masterSize = new Dimension(master.getWidth(), master.getHeight());
            renderingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            renderingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            renderingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            renderingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            renderingHints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        }

        public BufferedImage getScaledInstanceToFit(Dimension size) {
            return getScaledInstance(getScaleFactorToFit(size));
        }

        public BufferedImage getScaledInstanceToFill(Dimension size) {
            return getScaledInstance(getScaleFactorToFill(size));
        }

        protected double getScaleFactor(int masterSize, int targetSize) {
            return (double) targetSize / (double) masterSize;
        }

        protected double getScaleFactorToFit(Dimension toFit) {
            double dScaleWidth = getScaleFactor(masterSize.width, toFit.width);
            double dScaleHeight = getScaleFactor(masterSize.height, toFit.height);
            return Math.min(dScaleHeight, dScaleWidth);
        }

        protected double getScaleFactorToFill(Dimension targetSize) {
            double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width);
            double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height);
            return Math.max(dScaleHeight, dScaleWidth);
        }

        protected BufferedImage getScaledInstance(double dScaleFactor) {
            BufferedImage imgScale = master;
            int targetWidth = (int) Math.round(masterSize.getWidth() * dScaleFactor);
            int targetHeight = (int) Math.round(masterSize.getHeight() * dScaleFactor);

            if (dScaleFactor <= 1.0d) {
                imgScale = getScaledDownInstance(targetWidth, targetHeight);
            } else {
                imgScale = getScaledUpInstance(targetWidth, targetHeight);
            }

            return imgScale;
        }

        protected BufferedImage getScaledDownInstance(
                int targetWidth,
                int targetHeight) {

            int type = (master.getTransparency() == Transparency.OPAQUE)
                    ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

            BufferedImage scaled = master;

            if (targetHeight > 0 || targetWidth > 0) {
                int width = master.getWidth();
                int height = master.getHeight();

                do {
                    if (width > targetWidth) {
                        width /= 2;
                        if (width < targetWidth) {
                            width = targetWidth;
                        }
                    }
                    if (height > targetHeight) {
                        height /= 2;
                        if (height < targetHeight) {
                            height = targetHeight;
                        }
                    }

                    BufferedImage tmp = new BufferedImage(Math.max(width, 1), Math.max(height, 1), type);
                    Graphics2D g2 = tmp.createGraphics();
                    g2.setRenderingHints(renderingHints);
                    g2.drawImage(scaled, 0, 0, width, height, null);
                    g2.dispose();

                    scaled = tmp;
                } while (width != targetWidth || height != targetHeight);
            } else {
                scaled = new BufferedImage(1, 1, type);
            }

            return scaled;
        }

        protected BufferedImage getScaledUpInstance(
                int targetWidth,
                int targetHeight) {

            int type = BufferedImage.TYPE_INT_ARGB;

            BufferedImage ret = (BufferedImage) master;
            int width = master.getWidth();
            int height = master.getHeight();

            do {
                if (width < targetWidth) {
                    width *= 2;
                    if (width > targetWidth) {
                        width = targetWidth;
                    }
                }

                if (height < targetHeight) {
                    height *= 2;
                    if (height > targetHeight) {
                        height = targetHeight;
                    }
                }

                BufferedImage tmp = new BufferedImage(width, height, type);
                Graphics2D g2 = tmp.createGraphics();
                g2.setRenderingHints(renderingHints);
                g2.drawImage(ret, 0, 0, width, height, null);
                g2.dispose();

                ret = tmp;
            } while (width != targetWidth || height != targetHeight);
            return ret;
        }
    }
}

此外, JLabel实际上与您的问题无关,我可能会使用自定义绘画工作流程来渲染缩放后的图像,但这就是我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM