Getting pixel RGB from a bufferedImage from the mo

2019-01-19 09:47发布

问题:

I am making a color chooser program with an image. The program first loads in the image and then when you hover over the image, it will get the current pixels RGB value off of the mouses X and Y position. I have set up the frame and loaded them image, can someone help me get it working with the pixels?

package net.ogpc.settings;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.io.File;
import java.io.IOException;

public class ColorChooser implements Runnable, MouseListener{
    public static String path = "FileIO Plug-Ins\\Resources\\color-picker.png";
    public static boolean running = false;
    public static String r = "100";
    public static String g = "100";
    public static String b = "100";
    JFrame frame = new JFrame("Choose A Color");
    JTextField JR = new JTextField();
    JTextField JG = new JTextField();
    JTextField JB = new JTextField();
    Container colorImage = new Container();
    Container east = new Container();
    public ColorChooser() {
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
        frame.setResizable(false);
        //set up JFrame
        east.setLayout(new GridLayout(3, 3));
        east.add(JR);
        east.add(JG);
        east.add(JB);
        frame.add(east);
        //import the color chooser image
        Import();
        frame.setVisible(true);
        running = true;
        run();
    }
    public void run() {
        while (running) {
            getPixel();
            try {
                    Thread.sleep(250);
            }catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
    public void getPixel() {

        //get it m9!
        JR.setText(r);
        JG.setText(g);
        JB.setText(b);      
        System.out.println("r: " + r + " g: " + g + " b: " + b);
    }
    public void Import() {
        colorImage.setLayout(new FlowLayout());
        try {
            File file = new File(path);
            BufferedImage image;
            image = ImageIO.read(file);
            JLabel label = new JLabel(new ImageIcon(image));
            label.addMouseListener(this);
            colorImage.add(label, BorderLayout.NORTH);
            frame.getContentPane().add(colorImage, BorderLayout.WEST);
        } catch (IOException ex) {
                ex.printStackTrace();
        }
    }
    public static void main(String[] args) {
        new ColorChooser();
    }
    public void mouseClicked(MouseEvent arg0) {
    }
    public void mouseEntered(MouseEvent arg0) {
    }
    public void mouseExited(MouseEvent arg0) {
    }
    public void mousePressed(MouseEvent arg0) {
        //each time you click on the image... print out the pixel RGB here

    }
    public void mouseReleased(MouseEvent arg0) {
    }
}

回答1:

Your while-loop scares me, it says that you may not understand how Swing or event driven environments work. The short of it is, you don't need it, nor should you use this kind of technique in the future...

Basically, you are going to need access to a BufferedImage instance of the image, as this provides access to the underlying raster data.

If you are careful with your layouts, you can use a JLabel to display the image and simply add a MouseMotionListener to it and monitor the mouse movements, picking up the packed int color of the pixel below it.

You will then need to translate this packed int into RGB values. Now you could do some bit manipulation, but to be honest, using Color(int) is simpler.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class ColorPicky {

    public static void main(String[] args) {
        new ColorPicky();
    }

    public ColorPicky() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;
        private JLabel label;

        private JPanel fields;
        private JTextField red;
        private JTextField green;
        private JTextField blue;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            label = new JLabel();
            try {
                img = ImageIO.read(new File("C:\\hold\\thumbnails\\issue459.jpg"));
                label.setIcon(new ImageIcon(img));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            add(label, gbc);

            fields = new JPanel();
            fields.setBorder(new EmptyBorder(5, 5, 5, 5));
            red = new JTextField(3);
            green = new JTextField(3);
            blue = new JTextField(3);
            fields.add(red);
            fields.add(green);
            fields.add(blue);
            add(fields, gbc);

            label.addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    int packedInt = img.getRGB(e.getX(), e.getY());
                    Color color = new Color(packedInt, true);
                    fields.setBackground(color);
                    red.setText(Integer.toString(color.getRed()));
                    green.setText(Integer.toString(color.getGreen()));
                    blue.setText(Integer.toString(color.getBlue()));
                }
            });

        }

    }

}

I think you might like to spend some time reading through...

  • Creating a GUI in Swing
  • Concurrency in Swing
  • BufferedImage JavaDocs