如何将图标从 JLabel 转换为 BufferedImage?
Posted
技术标签:
【中文标题】如何将图标从 JLabel 转换为 BufferedImage?【英文标题】:How to convert Icon from JLabel into BufferedImage? 【发布时间】:2011-09-16 03:00:24 【问题描述】:简单,非常直截了当,但我和谷歌叔叔似乎感到困惑。
我有一个 JLabel
已经有自己的 Icon
。
如何将JLabel
得到的Icon
转换成BufferedImage
?
有什么办法吗:我试着像这样多次casting ..
final BufferedImage bf1 = (BufferedImage)((Image)jll_img.getIcon());
..但它失败了。
【问题讨论】:
【参考方案1】:import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import java.net.URL;
class GetImage
public static void main(String[] args) throws Exception
final String text = "Mt Stromlo at sunset";
final URL url = new URL(
"http://i.stack.imgur.com/lxthA.jpg");
SwingUtilities.invokeLater(new Runnable()
public void run()
ImageIcon imageIcon = new ImageIcon(url);
JLabel imageLabel = new JLabel(
text,
imageIcon,
SwingConstants.CENTER);
JOptionPane.showMessageDialog(null, imageLabel);
Icon icon = imageLabel.getIcon();
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.setColor(Color.WHITE);
g.drawString(text,10,20);
g.dispose();
JOptionPane.showMessageDialog(
null,
new JLabel(new ImageIcon(bi)));
);
这里有一些来自 Sun 论坛的旧代码,用于处理在内存中创建的图像。
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.swing.*;
class ImageCacheTest
private JLabel imageLabel;
private Dimension halfScreenSize;
private Random random;
private JProgressBar memory;
private Font bigFont = new Font("Arial", Font.BOLD, 30);
private int count = 0;
private int startMem = 0;
private int maxMem = 0;
private int peakMem = 0;
private int useMem = 0;
ImageCacheTest()
startMem = ((int) Runtime.getRuntime().freeMemory());
maxMem = ((int) Runtime.getRuntime().freeMemory());
peakMem = ((int) Runtime.getRuntime().freeMemory());
JPanel p = new JPanel(new BorderLayout(4, 4));
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
halfScreenSize = new Dimension(d.width / 2, d.height / 2);
//halfScreenSize = new Dimension(d.width - 11, d.height - 51);
random = new Random();
imageLabel = new JLabel(new ImageIcon(convertToFromBytes(getImage())));
memory = new JProgressBar(0, (int) Runtime.getRuntime().maxMemory());
p.add(imageLabel, BorderLayout.CENTER);
p.add(memory, BorderLayout.SOUTH);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(p);
f.setLocation(150, 150);
f.pack();
f.setVisible(true);
Runnable r = new Runnable()
@Override
public void run()
while (true)
try
imageLabel.setIcon(new ImageIcon(convertToFromBytes(getImage())));
memory.setValue((int) Runtime.getRuntime().freeMemory());
useMem = ((int) Runtime.getRuntime().freeMemory());
Thread.sleep(30);
catch (InterruptedException ex)
//something exceptio
finally
// alive that if required
;
Thread t = new Thread(r);
t.start();
private BufferedImage getImage()
GradientPaint gp = new GradientPaint(0f, 0f, new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)),
(float) halfScreenSize.width, (float) halfScreenSize.width, new Color(random.nextInt(128), random.nextInt(128), random.nextInt(128)));
BufferedImage bi = new BufferedImage(halfScreenSize.width, halfScreenSize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setPaint(gp);
g2d.fillRect(0, 0, halfScreenSize.width, halfScreenSize.height);
g2d.setFont(bigFont);
g2d.setColor(Color.BLACK);
if (maxMem < ((int) Runtime.getRuntime().freeMemory()))
maxMem = ((int) Runtime.getRuntime().freeMemory());
if (peakMem > ((int) Runtime.getRuntime().freeMemory()))
peakMem = ((int) Runtime.getRuntime().freeMemory());
useMem = ((int) Runtime.getRuntime().freeMemory()) - useMem;
g2d.drawString("" + ++count, 20, 100);
g2d.drawString("JVM memory status ---> ", 20, 195);
g2d.drawString("tot. memory ---> " + ((int) Runtime.getRuntime().totalMemory()), 20, 240);
g2d.drawString("max. memory ---> " + ((int) Runtime.getRuntime().maxMemory()), 20, 270);
g2d.drawString("free on startUp ---> " + startMem, 20, 300);
g2d.drawString("max free memory ---> " + maxMem, 20, 350);
g2d.drawString("min free memory ---> " + peakMem, 20, 380);
g2d.drawString("act free memory ---> " + ((int) Runtime.getRuntime().freeMemory()), 20, 410);
g2d.drawString("usage of memory ---> " + useMem, 20, 450);
g2d.dispose();
return bi;
/** Not entirely sure this method is necessary for indicating 'no cache',
but since the claim was specific to byte arrays, we'll do it. */
private Image convertToFromBytes(BufferedImage image)
try
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
return Toolkit.getDefaultToolkit().createImage(baos.toByteArray());
catch (Exception e)
return null;
public static void main(String[] args)
Runnable r = new Runnable()
@Override
public void run()
ImageCacheTest ict = new ImageCacheTest();
;
SwingUtilities.invokeLater(r);
截图
该代码的屏幕截图,宽度降至 ¼ 屏幕宽度。
【讨论】:
@Andrew Thompson :-) 正如我所说,回到你的代码,你可以将你的 Goblin's-Edge-Code 添加到你的帖子中,然后我会从这个帖子中删除我的帖子,用我的尊重 @mKorbel:“您可以将 Goblin's-Edge-Code 添加到您的帖子中”。完毕。顺便说一句,喜欢这种表达方式——胜过“尖端”。 ;) @Andrew Thompson phhhhhhhhaaa 和我一样好...,没错,谢谢 +1 好例子。不要忽略dispose()
createGraphics()
返回的图形实例。【参考方案2】:
这是最简单的方法:
labelPicture = new JLabel("Picture");
labelPicture.setIcon(new ImageIcon("picture.png"));
.
.
ImageIcon icon = (ImageIcon)labelPicture.getIcon()
BufferedImage img = (BufferedImage)((Image) icon.getImage());
【讨论】:
【参考方案3】:为了放大@Andrew Thompson 的answer,请注意实现Icon
接口的对象知道如何绘制某些东西,但可能还没有被要求这样做。相比之下,BufferedImage 具有“可访问的图像数据缓冲区”,您的程序必须通过调用 paintIcon()
方法来呈现它。这是一个相关的example。
【讨论】:
【参考方案4】:您不能将 ImageIcon 转换为 Image,因为它不是子类。不过,ImageIcon 确实有一个方法 getImage()
返回和 Image。见here
【讨论】:
注意JLabel
返回的Icon
不一定是ImageIcon
,&Icon
没有getImage()
方法。此外,从ImageIcon.getImage()
返回的Image
不能保证是BufferedImage
。使用我的回复中概述的方法更安全。以上是关于如何将图标从 JLabel 转换为 BufferedImage?的主要内容,如果未能解决你的问题,请参考以下文章