自动缩放ImageIcon以标签大小
在我的JFrame上,我使用下面的代码在面板上显示图像:
ImageIcon img= new ImageIcon("res.png"); jLabel.setIcon(img);
我想“自动调整”标签中的图片。 事实上,有时图像尺寸只有几个像素,有时甚至更多。
有没有办法设置标签的大小,然后自动大小的标签中的图像?
这是一个棘手的问题。 您突出显示了使用JLabel
来显示图像的事实,这是一种标准的做事方式,但是, JLabel
是一个复杂的小野兽,带有文本,图标和文本alignment和定位。
如果您不需要所有额外的function,我只需创build一个自定义组件,可以绘制缩放的图像…
接下来的问题是,你想如何缩放图像? 你想保持图像的宽高比吗? 你想“适合”或“填充”图像的可用空间。
@大卫是对的。 您应该尽可能避免使用Image#getScaledInstance
因为它不是最快的,但更重要的是,它通常不会提供最高的质量。
适合vs填充
下面的例子是相当简单的(从我的代码库中借用很多,所以它可能也有点复杂))。 它可以使用背景缩放线程,但我会根据原始图像的潜在大小决定。
public class ResizableImage { public static void main(String[] args) { new ResizableImage(); } public ResizableImage() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } try { BufferedImage image = ImageIO.read(new File("/path/to/your/image")); JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ScalablePane(image)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } catch (Exception exp) { exp.printStackTrace(); } } }); } public class ScalablePane extends JPanel { private Image master; private boolean toFit; private Image scaled; public ScalablePane(Image master) { this(master, true); } public ScalablePane(Image master, boolean toFit) { this.master = master; setToFit(toFit); } @Override public Dimension getPreferredSize() { return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(this), master.getHeight(this)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Image toDraw = null; if (scaled != null) { toDraw = scaled; } else if (master != null) { toDraw = master; } if (toDraw != null) { int x = (getWidth() - toDraw.getWidth(this)) / 2; int y = (getHeight() - toDraw.getHeight(this)) / 2; g.drawImage(toDraw, x, y, this); } } @Override public void invalidate() { generateScaledInstance(); super.invalidate(); } public boolean isToFit() { return toFit; } public void setToFit(boolean value) { if (value != toFit) { toFit = value; invalidate(); } } protected void generateScaledInstance() { scaled = null; if (isToFit()) { scaled = getScaledInstanceToFit(master, getSize()); } else { scaled = getScaledInstanceToFill(master, getSize()); } } protected BufferedImage toBufferedImage(Image master) { Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); BufferedImage image = createCompatibleImage(masterSize); Graphics2D g2d = image.createGraphics(); g2d.drawImage(master, 0, 0, this); g2d.dispose(); return image; } public Image getScaledInstanceToFit(Image master, Dimension size) { Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); return getScaledInstance( toBufferedImage(master), getScaleFactorToFit(masterSize, size), RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); } public Image getScaledInstanceToFill(Image master, Dimension size) { Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); return getScaledInstance( toBufferedImage(master), getScaleFactorToFill(masterSize, size), RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); } public Dimension getSizeToFit(Dimension original, Dimension toFit) { double factor = getScaleFactorToFit(original, toFit); Dimension size = new Dimension(original); size.width *= factor; size.height *= factor; return size; } public Dimension getSizeToFill(Dimension original, Dimension toFit) { double factor = getScaleFactorToFill(original, toFit); Dimension size = new Dimension(original); size.width *= factor; size.height *= factor; return size; } public double getScaleFactor(int iMasterSize, int iTargetSize) { return (double) iTargetSize / (double) iMasterSize; } public double getScaleFactorToFit(Dimension original, Dimension toFit) { double dScale = 1d; if (original != null && toFit != null) { double dScaleWidth = getScaleFactor(original.width, toFit.width); double dScaleHeight = getScaleFactor(original.height, toFit.height); dScale = Math.min(dScaleHeight, dScaleWidth); } return dScale; } public double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) { double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width); double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height); return Math.max(dScaleHeight, dScaleWidth); } public BufferedImage createCompatibleImage(Dimension size) { return createCompatibleImage(size.width, size.height); } public BufferedImage createCompatibleImage(int width, int height) { GraphicsConfiguration gc = getGraphicsConfiguration(); if (gc == null) { gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); } BufferedImage image = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT); image.coerceData(true); return image; } protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) { BufferedImage imgScale = img; int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor); int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor); if (dScaleFactor <= 1.0d) { imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); } else { imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); } return imgScale; } protected BufferedImage getScaledDownInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint, boolean higherQuality) { int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; BufferedImage ret = (BufferedImage) img; if (targetHeight > 0 || targetWidth > 0) { int w, h; if (higherQuality) { // Use multi-step technique: start with original size, then // scale down in multiple passes with drawImage() // until the target size is reached w = img.getWidth(); h = img.getHeight(); } else { // Use one-step technique: scale directly from original // size to target size with a single drawImage() call w = targetWidth; h = targetHeight; } do { if (higherQuality && w > targetWidth) { w /= 2; if (w < targetWidth) { w = targetWidth; } } if (higherQuality && h > targetHeight) { h /= 2; if (h < targetHeight) { h = targetHeight; } } BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.drawImage(ret, 0, 0, w, h, null); g2.dispose(); ret = tmp; } while (w != targetWidth || h != targetHeight); } else { ret = new BufferedImage(1, 1, type); } return ret; } protected BufferedImage getScaledUpInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint, boolean higherQuality) { int type = BufferedImage.TYPE_INT_ARGB; BufferedImage ret = (BufferedImage) img; int w, h; if (higherQuality) { // Use multi-step technique: start with original size, then // scale down in multiple passes with drawImage() // until the target size is reached w = img.getWidth(); h = img.getHeight(); } else { // Use one-step technique: scale directly from original // size to target size with a single drawImage() call w = targetWidth; h = targetHeight; } do { if (higherQuality && w < targetWidth) { w *= 2; if (w > targetWidth) { w = targetWidth; } } if (higherQuality && h < targetHeight) { h *= 2; if (h > targetHeight) { h = targetHeight; } } BufferedImage tmp = new BufferedImage(w, h, type); Graphics2D g2 = tmp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); g2.drawImage(ret, 0, 0, w, h, null); g2.dispose(); ret = tmp; tmp = null; } while (w != targetWidth || h != targetHeight); return ret; } } }
有没有办法设置标签的大小
重写JLabel
getPreferredSize()
并返回所需的Dimension
,但是因为JLabel
将自己调整为其内容,所以只需要调整添加到JLabel
的图片大小。
然后自动化标签中的图像?
您将不得不根据所需的宽度和高度来调整图像大小(而不是简单地将其添加到JLabel
,而JLabel
将根据图像大小resize)。
我不build议Image.getScaledInstance(..)
在这里阅读更多:
- Image.getScaledInstance()的风险主要问题是:
Image.getScaledInstance()
不返回完成的缩放图像。 当图像像素被使用时,它在很大程度上留下了缩放工作。
以下是我用来规避由getScaledInstance
创build的问题的自定义方法:
public static BufferedImage resize(BufferedImage 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; }
您可以通过以下方式创build图片:
BufferedImage image=ImageIO.read(..); BufferedImage resizedImage=resize(image,100,100);//resize the image to 100x100
也可以通过覆盖JLabel
的paintComponent
方法,并绘制宽度和高度与JLabel
的image
。 如果您希望在调整父container
大小时调整图像大小,则可以在父容器上应用WindowListener
,并在每次调整父容器时repaint
Jlabel
实例。 这里是演示:
import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.ImageIcon; import javax.swing.SwingUtilities; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class LabelDemo extends JFrame { ImageIcon imageIcon; MyJLabel jLabel ; public LabelDemo () { super("JLabel Demo"); } public void createAndShowGUI() { imageIcon = new ImageIcon("apple.png"); jLabel = new MyJLabel(imageIcon); getContentPane().add(jLabel); addWindowListener( new WindowAdapter() { public void windowResized(WindowEvent evt) { jLabel.repaint(); } }); setSize(300,100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); jLabel.repaint(); } public static void main(String st[]) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { LabelDemo demo = new LabelDemo(); demo.createAndShowGUI(); } }); } } class MyJLabel extends JLabel { ImageIcon imageIcon; public MyJLabel(ImageIcon icon) { super(); this.imageIcon = icon; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(imageIcon.getImage(),0,0,getWidth(),getHeight(),this); } }
您可以使用拉伸图标 。
图像将自动resize以填充标签可用的空间。 您可以控制图像是按比例缩放还是完全填充区域。
使用StretchIcon
比其他链接中build议的自定义绘画更灵活,因为您可以从支持图标的任何组件上自动resize中受益。
StretchIcon.java:
import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.net.URL; import javax.swing.ImageIcon; /** * An <CODE>Icon</CODE> that scales its image to fill the component area, excluding any border or insets, optionally maintaining the image's * aspect ratio by padding and centering the scaled image horizontally or vertically. * <P> * The class is a drop-in replacement for <CODE>ImageIcon</CODE>, except that the no-argument constructor is not supported. * <P> * As the size of the Icon is determined by the size of the component in which it is displayed, <CODE>StretchIcon</CODE> must only be used * in conjunction with a component and layout that does not depend on the size of the component's Icon. * * @version 1.1 01/15/2016 * @author Darryl */ public class StretchIcon extends ImageIcon { /** * */ private static final long serialVersionUID = 1L; /** * Determines whether the aspect ratio of the image is maintained. Set to <code>false</code> to allow th image to distort to fill the * component. */ protected boolean proportionate = true; /** * Creates a <CODE>StretchIcon</CODE> from an array of bytes. * * @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG * * @see ImageIcon#ImageIcon(byte[]) */ public StretchIcon(byte[] imageData) { super(imageData); } /** * Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior. * * @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(byte[]) */ public StretchIcon(byte[] imageData, boolean proportionate) { super(imageData); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from an array of bytes. * * @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG * @param description a brief textual description of the image * * @see ImageIcon#ImageIcon(byte[], java.lang.String) */ public StretchIcon(byte[] imageData, String description) { super(imageData, description); } /** * Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior. * * @see ImageIcon#ImageIcon(byte[]) * @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG * @param description a brief textual description of the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(byte[], java.lang.String) */ public StretchIcon(byte[] imageData, String description, boolean proportionate) { super(imageData, description); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the image. * * @param image the image * * @see ImageIcon#ImageIcon(java.awt.Image) */ public StretchIcon(Image image) { super(image); } /** * Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior. * * @param image the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.awt.Image) */ public StretchIcon(Image image, boolean proportionate) { super(image); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the image. * * @param image the image * @param description a brief textual description of the image * * @see ImageIcon#ImageIcon(java.awt.Image, java.lang.String) */ public StretchIcon(Image image, String description) { super(image, description); } /** * Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior. * * @param image the image * @param description a brief textual description of the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.awt.Image, java.lang.String) */ public StretchIcon(Image image, String description, boolean proportionate) { super(image, description); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the specified file. * * @param filename a String specifying a filename or path * * @see ImageIcon#ImageIcon(java.lang.String) */ public StretchIcon(String filename) { super(filename); } /** * Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior. * * @param filename a String specifying a filename or path * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.lang.String) */ public StretchIcon(String filename, boolean proportionate) { super(filename); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the specified file. * * @param filename a String specifying a filename or path * @param description a brief textual description of the image * * @see ImageIcon#ImageIcon(java.lang.String, java.lang.String) */ public StretchIcon(String filename, String description) { super(filename, description); } /** * Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior. * * @param filename a String specifying a filename or path * @param description a brief textual description of the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.awt.Image, java.lang.String) */ public StretchIcon(String filename, String description, boolean proportionate) { super(filename, description); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the specified URL. * * @param location the URL for the image * * @see ImageIcon#ImageIcon(java.net.URL) */ public StretchIcon(URL location) { super(location); } /** * Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior. * * @param location the URL for the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.net.URL) */ public StretchIcon(URL location, boolean proportionate) { super(location); this.proportionate = proportionate; } /** * Creates a <CODE>StretchIcon</CODE> from the specified URL. * * @param location the URL for the image * @param description a brief textual description of the image * * @see ImageIcon#ImageIcon(java.net.URL, java.lang.String) */ public StretchIcon(URL location, String description) { super(location, description); } /** * Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior. * * @param location the URL for the image * @param description a brief textual description of the image * @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to * fill the component. * * @see ImageIcon#ImageIcon(java.net.URL, java.lang.String) */ public StretchIcon(URL location, String description, boolean proportionate) { super(location, description); this.proportionate = proportionate; } /** * Paints the icon. The image is reduced or magnified to fit the component to which it is painted. * <P> * If the proportion has not been specified, or has been specified as <code>true</code>, the aspect ratio of the image will be preserved * by padding and centering the image horizontally or vertically. Otherwise the image may be distorted to fill the component it is * painted to. * <P> * If this icon has no image observer,this method uses the <code>c</code> component as the observer. * * @param c the component to which the Icon is painted. This is used as the observer if this icon has no image observer * @param g the graphics context * @param x not used. * @param y not used. * * @see ImageIcon#paintIcon(java.awt.Component, java.awt.Graphics, int, int) */ @Override public synchronized void paintIcon(Component c, Graphics g, int x, int y) { Image image = getImage(); if (image == null) { return; } Insets insets = ((Container) c).getInsets(); x = insets.left; y = insets.top; int w = c.getWidth() - x - insets.right; int h = c.getHeight() - y - insets.bottom; if (proportionate) { int iw = image.getWidth(c); int ih = image.getHeight(c); if ((iw * h) < (ih * w)) { iw = (h * iw) / ih; x += (w - iw) / 2; w = iw; } else { ih = (w * ih) / iw; y += (h - ih) / 2; h = ih; } } ImageObserver io = getImageObserver(); /* * Added this code to generate nicer looking results when scaling. - bspkrs * BEGIN CHANGES */ BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2d = bi.createGraphics(); g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)); g2d.drawImage(image, 0, 0, w, h, io == null ? c : io); g2d.dispose(); /* * END CHANGES */ g.drawImage(bi, x, y, w, h, io == null ? c : io); } /** * Overridden to return 0. The size of this Icon is determined by the size of the component. * * @return 0 */ @Override public int getIconWidth() { return 0; } /** * Overridden to return 0. The size of this Icon is determined by the size of the component. * * @return 0 */ @Override public int getIconHeight() { return 0; } }
private Image fitimage(Image img , int w , int h) { int width=img.getWidth(this); int height=img.getHeight(this); BufferedImage resizedimage; if(width>w && height>h){ resizedimage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); Graphics2D g2 = resizedimage.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(img, 0, 0,w,h,null); g2.dispose(); } else { resizedimage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); Graphics2D g2 = resizedimage.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2.drawImage(img, 0, 0,width,height,null); g2.dispose(); } return resizedimage; }
试试这个function:
public static BufferedImage resize(BufferedImage 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; } BufferedImage image1=ImageIO.read(url.openStream()); BufferedImage resizedImage=resize(image,100,100); System.out.println("Load image into frame..."); icon=new ImageIcon(resizedImage);
easywayprogramming.com如何在java中调整imageicon大小
当我们将图像图标应用到button,标签或面板等任何组件时,由于该图像的大小而无法正确应用。 我们可以通过两种方式调整图像图标的大小。
-
第一种方法:Image img = myIcon2.getImage(); Image newimg = img.getScaledInstance(230,310,java.awt.Image.SCALE_SMOOTH);
newIcon = new ImageIcon(newimg); -
第二种方式:
Image img = myIcon2.getImage(); BufferedImage bi = new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_ARGB);
newIcon = new ImageIcon(bi);
尝试下面的链接easywayprogramming.blogspot.in:easywayprogramming.blogspot.in 浩调整图像图标在Java