【问题标题】:Wrong RGB values are returned返回错误的 RGB 值
【发布时间】:2021-09-05 16:12:53
【问题描述】:

我正在尝试获取图像像素的 RGB 值。 (鼠标经过的像素)。这是添加图像的代码和处理鼠标的代码::

/// I got this code somewhere from StackOverFlow; 
///Couldn't find the link; 

label = new JLabel();
            try {
// THIS PICTURE IS NOT MINE                
targetImg = ImageIO.read(new java.net.URL("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSFAhy8GM1F3_TyPjG7ezbeFRUy00PN4hpJCA&usqp=CAU"));
                label.setIcon(new ImageIcon(rescale(targetImg)));
           

            panel1.add(label);

            fields = new JPanel();
            fields.setBorder(new EmptyBorder(5, 5, 5, 5));
            red = new JTextField(3);
            green = new JTextField(3);
            blue = new JTextField(3);
            red.setEditable(false);
            green.setEditable(false);
            blue.setEditable(false);
            fields.add(red);
            fields.add(green);
            fields.add(blue);
            panel1.add(fields);
            
      label.addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                try{
                    int packedInt = targetImg.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()));
                   }
                   
                   catch (ArrayIndexOutOfBoundsException exception)  { }
                     }
            });
            
             } catch (IOException ex) {
                ex.printStackTrace();
            }

这可以正常运行和编译;但是,有时RGB返回的颜色不是我的鼠标所在的颜色;这是一张图片::

https://i.stack.imgur.com/R5qIx.png

注意:白色十字是它所在位置的大概位置;屏幕截图显然也不用鼠标。

代码也很滞后。有时它会挂在一个像素上,我必须等到它再次运行。

为什么会发生这种情况,我可以做些什么来防止这种情况发生?我该如何解决这个问题?

【问题讨论】:

  • rescale 是做什么的?如果它如其名称所述,您不应该在重新缩放的图像上调用getRGB,而不是原始图像吗?
  • 发布minimal reproducible example 来演示问题,因此我们不必问上述问题。 有时它会挂在一个像素上 - 不要使用空的 catch 块。如果您没有任何异常代码,您如何知道何时出现异常?您应该显示异常消息。我猜你得到了异常,因为你有一个重新缩放的图像。
  • 注意,如果你想防止延迟,你应该使用 invokeLater 在 EDT 线程上运行任何 GUI 代码,就像 SwingUtilities.invokeLater(new Runnable(){public void run(){fields.setBackground(color);;}});

标签: java swing jpanel rgb mouselistener


【解决方案1】:

由于您只提供了一个代码 sn-p,我创建了以下 GUI。

由于图片太小,我把它放在RGB显示器下。

主要问题是匹配坐标系,以便鼠标指针指向图像中的像素。当您将图像放入JLabel 时,您必须将鼠标坐标转换为图像坐标。

我通过创建绘图JPanel 来回避坐标系问题。通过在绘图JPanel 上绘制图像并将MouseMotionListener 添加到绘图JPanel,鼠标坐标与图像坐标匹配。

我通过调用 SwingUtilities invokeLater 方法启动了 Swing 应用程序。此方法确保在Event Dispatch Thread 上创建和执行 Swing 组件。

我创建了一个JFrame、一个RGB JPanel 和一个绘图JPanelJFrame 方法必须按特定顺序执行。这是我用于所有 Swing 应用程序的顺序。

RGB JPanel 使用FlowLayout 分隔红色、绿色和蓝色JTextFields

绘图JPanel 绘制图像。绘图JPanel 与图像大小相同。同样,通过在绘图JPanel 上绘制图像并将MouseMotionListener 添加到绘图JPanel,鼠标坐标与图像坐标匹配。

我将ColorListener 设为一个单独的类。我基本上把你的代码复制到了mouseMoved 方法中。

这是完整的可运行代码。我将类设置为内部类,因此我可以将此代码粘贴为一个块。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class RGBProcessor implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new RGBProcessor());
    }
    
    private BufferedImage image;
    
    private Color panelColor;
    
    private DrawingPanel drawingPanel;
    
    private JPanel rgbPanel;
    
    private JTextField redField;
    private JTextField greenField;
    private JTextField blueField;
    
    public RGBProcessor() {
        this.panelColor = Color.RED;
        this.image = getImage();
        this.drawingPanel = new DrawingPanel(this, image);
        this.rgbPanel = createRGBPanel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("RGB Processor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(rgbPanel, BorderLayout.BEFORE_FIRST_LINE);
        frame.add(drawingPanel, BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createRGBPanel() {
        JPanel panel = new JPanel();
        panel.setBackground(panelColor);
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        redField = new JTextField(4);
        redField.setEditable(false);
        panel.add(redField);
        
        greenField = new JTextField(4);
        greenField.setEditable(false);
        panel.add(greenField);
        
        blueField = new JTextField(4);
        blueField.setEditable(false);
        panel.add(blueField);
        
        return panel;
    }
    
    private BufferedImage getImage() {
        try {
            return ImageIO.read(new URL("https://encrypted-tbn0.gstatic.com/"
                    + "images?q=tbn:ANd9GcSFAhy8GM1F3_TyPjG7ezbe"
                    + "FRUy00PN4hpJCA&usqp=CAU"));
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public void setPanelColor(Color color) {
        this.panelColor = color;
        this.rgbPanel.setBackground(color);
    }
    
    public JTextField getRedField() {
        return redField;
    }

    public JTextField getGreenField() {
        return greenField;
    }

    public JTextField getBlueField() {
        return blueField;
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private BufferedImage image;

        public DrawingPanel(RGBProcessor frame, BufferedImage image) {
            this.image = image;
            this.setPreferredSize(new Dimension(image.getWidth(), 
                    image.getHeight()));
            this.addMouseMotionListener(new ColorListener(frame, image));
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }
        
    }
    
    public class ColorListener extends MouseAdapter {
        
        private RGBProcessor frame;
        
        private BufferedImage image;
        
        public ColorListener(RGBProcessor frame, BufferedImage image) {
            this.frame = frame;
            this.image = image;
        }

        @Override
        public void mouseMoved(MouseEvent event) {
            int packedInt = image.getRGB(event.getX(), event.getY());
            Color color = new Color(packedInt, true);
            frame.setPanelColor(color);
            frame.getRedField().setText(Integer.toString(color.getRed()));
            frame.getGreenField().setText(Integer.toString(color.getGreen()));
            frame.getBlueField().setText(Integer.toString(color.getBlue()));
        }

    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 2015-06-19
    • 2011-03-04
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多