Java Swing: 令图像以等比例缩放或完全填充方式,自适应JLabel等组件大小

您所在的位置:网站首页 怎么把图片尺寸缩小做头像呢 Java Swing: 令图像以等比例缩放或完全填充方式,自适应JLabel等组件大小

Java Swing: 令图像以等比例缩放或完全填充方式,自适应JLabel等组件大小

2024-07-17 19:10:17| 来源: 网络整理| 查看: 265

Java Swing:令图像以等比例缩放或完全填充方式,自适应JLabel、JButton等组件大小 代码Demo注释 向如下工具类中的方法传入图像信息,来获得一个 Icon对象。此 Icon对象能够自适应 JLabel或 JButton大小进行缩放。

代码中的方法为静态方法,可直接使用。后续 Demo 和 注释 部分对代码内容和设计思路进行了详细介绍,希望能为大家提供一些参考,可略过。

代码 import java.net.URL; import java.awt.Point; import java.awt.Image; import java.awt.Graphics; import java.awt.Dimension; import javax.swing.ImageIcon; /**Title: SwingUtil.java * Swing工具类 * * @author Run * @date 2019-08-20 */ public class SwingUtil { /**创建一个可以自适应组件大小的ImageIcon对象 * @param image 从 Image 对象来创建ImageIcon * @param constrained 是否等比例缩放 。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(Image image, boolean constrained) { ImageIcon icon = new ImageIcon(image) { @Override public synchronized void paintIcon(java.awt.Component cmp, Graphics g, int x, int y) { //初始化参数 Point startPoint = new Point(0, 0);//默认绘制起点 Dimension cmpSize = cmp.getSize();//获取组件大小 Dimension imgSize = new Dimension(getIconWidth(), getIconHeight());//获取图像大小 //计算绘制起点和区域 if(constrained) {//等比例缩放 //计算图像宽高比例 double ratio = 1.0*imgSize.width/imgSize.height; //计算等比例缩放后的区域大小 imgSize.width = (int) Math.min(cmpSize.width, ratio*cmpSize.height); imgSize.height = (int) (imgSize.width/ratio); //计算绘制起点 startPoint.x = (int) (cmp.getAlignmentX()*(cmpSize.width - imgSize.width)); startPoint.y = (int) (cmp.getAlignmentY()*(cmpSize.height - imgSize.height)); } else {//完全填充 imgSize = cmpSize; } //根据起点和区域大小进行绘制 if(getImageObserver() == null) { g.drawImage(getImage(), startPoint.x, startPoint.y, imgSize.width, imgSize.height, cmp); } else { g.drawImage(getImage(), startPoint.x, startPoint.y, imgSize.width, imgSize.height, getImageObserver()); } }; }; return icon; } /**创建一个可以自适应组件大小的Icon对象 * @param filename 指定文件名或者路径的字符串 * @param constrained 是否等比例缩放。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(String filename, boolean constrained) { return createAutoAdjustIcon(new ImageIcon(filename).getImage(), constrained); } /**创建一个可以自适应组件大小的ImageIcon对象 * @param url 从指定的 URL 对象来创建ImageIcon * @param constrained 是否等比例缩放 。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(URL url, boolean constrained) { return createAutoAdjustIcon(new ImageIcon(url).getImage(), constrained); } }

使用:

通过代码中SwingUtil.createAutoAdjustIcon(String , boolean)等静态方法,创建一个能自适应组件大小的ImageIcon对象。在实现了setIcon(Icon)方法的JComponent组件(如JLabel、JButton)中,调用setIcon(Icon)方法,设置组件图标为该ImageIcon。

注意:

在组件(如JLabel)中最好只放置此Icon,不添加其它图标或文本,否则这些内容之间会产生覆盖。当图像属性设置为等比例缩放时,可以调用JComponent的setAlignmentX(float)或setAlignmentY(float)方法,分别设置图标的水平或垂直对齐方式。 Demo

下面的Demo展示了一张网络图片在JLabel里的三种适应样式(等比例缩放、完全填充、不缩放)。

package demo; import java.net.URL; import java.awt.Point; import java.awt.Image; import java.awt.Graphics; import java.awt.Dimension; import javax.swing.ImageIcon; import javax.swing.JLabel; import java.awt.Color; import java.awt.GridLayout; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.JFrame; import javax.swing.WindowConstants; import javax.swing.border.LineBorder; import java.net.MalformedURLException; /**Title: Demo.java * 示例代码 * * @author Run * @date 2019-08-20 */ public class Demo{ public static void main(String args[]){ SwingUtilities.invokeLater( () ->{ //运行示例代码 AutoAdjustIconDemo(); }); } /**图像自适应组件大小 * @date 2019-08-20 */ static void AutoAdjustIconDemo() { JFrame frame=new JFrame("Auto-adjust Icon"); JPanel panel=new JPanel(new GridLayout(1, 3, 10, 10)); //导入图片 Image image = null; try { //一张来自CSDN的默认用户头像 URL url = new URL("https://imgconvert.csdnimg.cn/" + "aHR0cHM6Ly9hdmF0YXIuY3Nkbi5uZXQvNy83L0IvMV9yYWxmX2h4MTYzY29tLmpwZw"); image = new ImageIcon(url).getImage(); } catch (MalformedURLException e) { System.out.println("HTTP ERROR 404"); } //等比例JLabel JLabel ratioLabel = new JLabel(); ratioLabel.setIcon(SwingUtil.createAutoAdjustIcon(image, true)); ratioLabel.setBorder(new LineBorder(Color.RED)); ratioLabel.setAlignmentX(0.5F); ratioLabel.setAlignmentY(0.5F); //不等比例JLabel JLabel filledLabel = new JLabel(); filledLabel.setIcon(SwingUtil.createAutoAdjustIcon(image, false)); filledLabel.setBorder(new LineBorder(Color.ORANGE)); //常规样式JLabel JLabel normalLabel = new JLabel(); normalLabel.setIcon(new ImageIcon(image)); normalLabel.setBorder(new LineBorder(Color.BLUE)); //JPanel内容 panel.add(ratioLabel); panel.add(filledLabel); panel.add(normalLabel); //JFrame内容 frame.getContentPane().add(panel); frame.setSize(600,480); //JFrame属性 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } } // /**Swing工具类 * * @author Run * @date 2019-08-20 */ class SwingUtil { /**创建一个可以自适应组件大小的ImageIcon对象 * @param image 从 Image 对象来创建ImageIcon * @param constrained 是否等比例缩放 。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(Image image, boolean constrained) { ImageIcon icon = new ImageIcon(image) { @Override public synchronized void paintIcon(java.awt.Component cmp, Graphics g, int x, int y) { //初始化参数 Point startPoint = new Point(0, 0);//默认绘制起点 Dimension cmpSize = cmp.getSize();//获取组件大小 Dimension imgSize = new Dimension(getIconWidth(), getIconHeight());//获取图像大小 //计算绘制起点和区域 if(constrained) {//等比例缩放 //计算图像宽高比例 double ratio = 1.0*imgSize.width/imgSize.height; //计算等比例缩放后的区域大小 imgSize.width = (int) Math.min(cmpSize.width, ratio*cmpSize.height); imgSize.height = (int) (imgSize.width/ratio); //计算绘制起点 startPoint.x = (int) (cmp.getAlignmentX()*(cmpSize.width - imgSize.width)); startPoint.y = (int) (cmp.getAlignmentY()*(cmpSize.height - imgSize.height)); } else {//完全填充 imgSize = cmpSize; } //根据起点和区域大小进行绘制 if(getImageObserver() == null) { g.drawImage(getImage(), startPoint.x, startPoint.y, imgSize.width, imgSize.height, cmp); } else { g.drawImage(getImage(), startPoint.x, startPoint.y, imgSize.width, imgSize.height, getImageObserver()); } }; }; return icon; } /**创建一个可以自适应组件大小的Icon对象 * @param filename 指定文件名或者路径的字符串 * @param constrained 是否等比例缩放。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(String filename, boolean constrained) { return createAutoAdjustIcon(new ImageIcon(filename).getImage(), constrained); } /**创建一个可以自适应组件大小的ImageIcon对象 * @param url 从指定的 URL 对象来创建ImageIcon * @param constrained 是否等比例缩放 。当为 true 时,可通过 * {@link javax.swing.JComponent#setAlignmentX(float)}和 * {@link javax.swing.JComponent#setAlignmentY(float)}方法设置组件对齐方式。 * @date 2019-08-20 */ public static ImageIcon createAutoAdjustIcon(URL url, boolean constrained) { return createAutoAdjustIcon(new ImageIcon(url).getImage(), constrained); } }

运行结果: 运行结果

注释

在Java Swing中,部分JComponent组件实现了setIcon(Icon)方法,如JLabel、JButton等。通过setIcon(Icon)可以在组件中设置需要显示的图像。其中的Icon接口有三个方法:

public interface Icon { /** * Draw the icon at the specified location. Icon implementations * may use the Component argument to get properties useful for * painting, e.g. the foreground or background color. */ void paintIcon(Component c, Graphics g, int x, int y); int getIconWidth(); int getIconHeight(); }

ImageIcon类实现了Icon接口。上面程序中的关键代码SwingUtil.createAutoAdjustIcon(String , boolean),便是通过覆盖ImageIcon里的paintIcon(Component, Graphics, int, int)方法,来实现图像的缩放功能。

Swing 使用的是 MVC 框架。组件模型会在程序在运行时,委托对应的UI对象进行内容绘制。所以,在JLabel对应的基本UI类javax.swing.plaf.basic.BasicLabelUI中,可以寻找到对应的图像显示代码。在其BasicLabelUI.paint(Graphics, javax.swing.JComponent)方法中,可以看到: BasicLabelUI.paint(Graphics, javax.swing.JComponent) 由此看出,JLabel中图像的绘制任务,最终转交给了Icon类的paintIcon(Component, Graphics, int, int)方法这里。

接下来的事情就简单了。在paintIcon(Component, Graphics, int, int)方法中,通过传入参数,可以获得:当前正在进行绘制的组件、图形上下文和图像左上角顶点。如果图像仅需要完全填充的样式,可以省略计算等比例缩放的过程,直接按照下面这样写:

public synchronized void paintIcon(java.awt.Component cmp, Graphics g, int x, int y) { g.drawImage(getImage(), 0, 0, cmp.getWidth(), cmp.getHeight(), cmp); }

java.awt.Graphics.drawImage(Image, int, int, int, int, ImageObserver)方法会自动将图像(Image参数)缩放到需要绘制的区域中。

当等比例缩放图片时,需要在调用drawImage(Image, int, int, int, int, ImageObserver)方法前,额外进行一些计算:

计算图像宽和高的像素比;依据图像像素比和组件的宽、高,计算组件能支持的最大图像尺寸;计算缩放后,图像宽高与组件宽高间的差值,并依据组件X轴、Y轴的对齐参数,求出图像左上角顶点的坐标;依据图像缩放后左上角顶点的坐标、缩放后的尺寸,对图像进行绘制。

即:

/* cmp 为需要进行绘制的 Component 组件 */ //初始化参数 Point startPoint = new Point(0, 0);//默认绘制起点 Dimension cmpSize = cmp.getSize();//获取组件大小 Dimension imgSize = new Dimension(getIconWidth(), getIconHeight());//获取图像大小 /* 等比例缩放,需要计算绘制起点和区域 */ //计算图像宽高比例 double ratio = 1.0*imgSize.width/imgSize.height; //计算等比例缩放后的区域大小 imgSize.width = (int) Math.min(cmpSize.width, ratio*cmpSize.height); imgSize.height = (int) (imgSize.width/ratio); //计算绘制起点 startPoint.x = (int) (cmp.getAlignmentX()*(cmpSize.width - imgSize.width)); startPoint.y = (int) (cmp.getAlignmentY()*(cmpSize.height - imgSize.height));

两种缩放方式整合在一起,并结合ImageIcon类的几个常用接口,便实现了文章开头部分的代码。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭