Как конвертировать Icon из JLabel в BufferedImage? - PullRequest
7 голосов
/ 16 июня 2011

Простой, очень прямой, но, кажется, дядя Гугл и я запутались.

У меня есть один JLabel, у которого уже есть свой Icon.

Как мне конвертировать Icon получено из JLabel в BufferedImage?

Есть ли способ обойти: я пытался умножить приведение , как это ..

 final BufferedImage bf1 = (BufferedImage)((Image)jll_img.getIcon());

..но это не удалось.

Ответы [ 4 ]

11 голосов
/ 16 июня 2011
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);
    }
}

Снимок экрана

Снимок экрана этого кода с шириной, уменьшенной до ¼ширина экрана.

Free Memory screenshot

4 голосов
/ 17 июня 2011

Чтобы усилить @ 1001 * ответ @Andrew Thompson, обратите внимание, что объект, который реализует интерфейс Icon, знает, как рисовать что-то, но его, возможно, не просили сделать этоеще.Напротив, BufferedImage имеет «доступный буфер данных изображения», который ваша программа должна отобразить, вызвав метод paintIcon().Вот связанный пример .

3 голосов
/ 20 января 2013

Это самый простой способ:

labelPicture = new JLabel("Picture");
labelPicture.setIcon(new ImageIcon("picture.png"));
.
.
ImageIcon icon = (ImageIcon)labelPicture.getIcon()
BufferedImage img = (BufferedImage)((Image) icon.getImage());
2 голосов
/ 16 июня 2011

Вы не можете привести ImageIcon к Image, потому что это не подкласс. ImageIcon имеет метод getImage(), который возвращает и Image, хотя. Смотри здесь

...