java imageicon大小_Java 自动缩放ImageIcon到标签大小

黄高爽
2023-12-01

小编典典

这是一个棘手的问题。你强调了一个事实,即你正在使用a JLabel来显示图像,这是标准的处理方式,但是却JLabel是一个复杂的小野兽,具有文本,图标以及文本的对齐和定位。

如果你不需要所有这些额外的功能,我将为你自己创建一个能够绘制缩放图像的自定义组件…

下一个问题是,你如何缩放图像?你是否要保持图像的长宽比?是否要将图像“适合”或“填充”到可用空间。

@大卫是正确的。你应该尽可能避免Image#getScaledInstance使用它,因为它不是最快的,但是更重要的是,通常它也不提供最高的质量。

适合与填充

以下示例非常简单(并且从我的代码库中借来了很多代码,因此可能还有些复杂;)。可以从后台缩放线程使用它,但是我将根据原始图像的潜在大小来做出决定。

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;

}

}

}

2020-03-05

 类似资料: