在Java中准确地绘制图像

在Java中准确地绘制图像,java,swing,jpanel,bufferedimage,paintcomponent,Java,Swing,Jpanel,Bufferedimage,Paintcomponent,在下面的代码中,我将一个2dim数组转换为一个缓冲图像(这可以工作,图像是二进制的(背景和白色))。然后我显示这个图像 我现在的问题是如何更新此图像(因为我想在循环的每一次运行中绘制一些未在此处显示的内容) 这也引出了我的第二个问题:我如何在这张图片上画一个点。(这也意味着如果我想在150100上画一个点,它应该在图像的像素150100上) 我尝试的是: g2d.setColor(Color.RED); g2d.drawLine(x, y, x, y); 虽然在每次运行中打开了一个新窗

在下面的代码中,我将一个2dim数组转换为一个缓冲图像(这可以工作,图像是二进制的(背景和白色))。然后我显示这个图像

我现在的问题是如何更新此图像(因为我想在循环的每一次运行中绘制一些未在此处显示的内容)

这也引出了我的第二个问题:我如何在这张图片上画一个点。(这也意味着如果我想在150100上画一个点,它应该在图像的像素150100上)

我尝试的是:

  g2d.setColor(Color.RED);
  g2d.drawLine(x, y, x, y);

虽然在每次运行中打开了一个新窗口,但我不认为这一点在正确的

,而不是构建一个图像,然后将其添加到JPanel中,您可以考虑通过覆盖PrimtEngel方法来查看面板上的绘图,如:

public class PainterPanel extends JPanel {
    public void paintComponent(Graphics g){     
        super.paintComponent(g);

        // draw a diagonal line from top left to bottom right
        Dimension d = getSize();
        g2.draw(new Line2D.Double(0,0,d.width,d.height));
    }
}
每次调用
repaint()
方法时都会调用此方法(例如,通过调整帧大小,或通过自己手动调用)。您可以进行任何类型的复杂处理,包括绘制点矩阵

唯一需要注意的是(如果您也坚持您的原始行为,这将是正确的)重新绘制是在一个单独的线程中进行的,因此您需要小心更新数据的时间和方式,以便以线程安全的方式完成

如何更新此图像

  • 要在图像上绘制,请使用bimg.getGraphics()获得的图形(然后像在
    paintComponent
    中一样使用它)
我如何在这张图片上画一个点

  • 若要在缓冲图像的特定点上绘制,请使用从上述答案检索的图形对象的任何方法。示例
    g.抽绳(150100150100)

    • 我给你举了个小例子

      基本上,它是一个
      JFrame
      ,带有一个名为
      ColorPanel
      的定制
      JPanel
      (与您的非常相似,有一些额外的方法,即
      drawDot(..)
      setBufferedImage(..)

      JFrame
      将初始化
      JPanel
      ,并添加一个
      buffereImage
      (在这种情况下为完全黑色)。此后,使用
      BufferedImage#setRGB(…)
      每隔2秒在
      图像上以随机坐标(图像边界内)绘制白点/像素

      我将计时器设置为更快(200毫秒),这就是图片开始显示的样子:

      注意:它是准确的,使其颜色成为一个明显的坐标,如
      drawPoint(0,0)
      ,您将看到(我没有演示这一点,因为屏幕截图不可能或没有任何用途)


      希望这能有所帮助。

      我认为必须覆盖
      JPanel的
      PreferredSize
      “尽管每次跑步都会打开一个新窗口”。因为每次调用showImage()都会创建一个新的JFrame。如需更多帮助,请发布SSCCE@David呵呵。。说得好。我被纠正了。
        g2d.setColor(Color.RED);
        g2d.drawLine(x, y, x, y);
      
      public class PainterPanel extends JPanel {
          public void paintComponent(Graphics g){     
              super.paintComponent(g);
      
              // draw a diagonal line from top left to bottom right
              Dimension d = getSize();
              g2.draw(new Line2D.Double(0,0,d.width,d.height));
          }
      }
      
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.event.ActionEvent;
      import java.awt.image.BufferedImage;
      import java.net.URL;
      import java.util.Random;
      import javax.imageio.ImageIO;
      import javax.swing.AbstractAction;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.SwingUtilities;
      import javax.swing.Timer;
      
      public class PixelDotOnImage {
      
          public PixelDotOnImage() throws Exception {
              JFrame frame = new JFrame();
              frame.setTitle("Random Pixel Dots On Image with Timer");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.setResizable(false);
      
              initComponents(frame);
      
              frame.pack();
              frame.setVisible(true);
          }
      
          public static void main(String[] args) {
      
              //create frame and components on EDT
              SwingUtilities.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          new PixelDotOnImage();
                      } catch (Exception ex) {
                          ex.printStackTrace();
                      }
                  }
              });
          }
      
          private void initComponents(JFrame frame) throws Exception {
      
              final BufferedImage bi = ImageIO.read(new URL("http://2.bp.blogspot.com/_KI3IRH6RxSs/S-uuLsgGJ3I/AAAAAAAAA5E/AA5mWBMLIvo/s1600/mat-black-lg.jpg"));
              final ColorPanel cPanel = new ColorPanel(bi);
              frame.add(cPanel);
      
              //create timer to color random pixels
              Timer timer = new Timer(2000, new AbstractAction() {
                  int xMax = bi.getWidth(), yMax = bi.getHeight();
                  Random rand = new Random();
      
                  @Override
                  public void actionPerformed(ActionEvent ae) {
      
                      int x = rand.nextInt(xMax);
                      int y = rand.nextInt(yMax);
      
                      if (cPanel.drawDot(x, y)) {
                          System.out.println("Drew white dot at: (" + x + "," + y + ")");
                      } else {
                          System.out.println("Cant draw white dot at: (" + x + "," + y + ")");
                      }
      
                  }
              });
      
              timer.start();
          }
      }
      
      class ColorPanel extends JPanel {
      
          private BufferedImage bimg;
          private Dimension dims;
      
          public ColorPanel(BufferedImage image) {
              bimg = image;
              dims = new Dimension(bimg.getWidth(), bimg.getHeight());
          }
      
          @Override
          public void paintComponent(Graphics g) {
              super.paintComponent(g);
              Graphics2D g2d = (Graphics2D) g;
              g2d.drawImage(bimg, 0, 0, null);
          }
      
          //this method will allow the changing of image
          public void setBufferedImage(BufferedImage newImg) {
              bimg = newImg;
          }
      
          //ths method will colour a pixel white
          public boolean drawDot(int x, int y) {
      
              if (x > dims.getWidth() || y > dims.getHeight()) {
                  return false;
              }
      
              bimg.setRGB(x, y,  0xFFFFFFFF);//white
      
              repaint();
              return true;
          }
      
          @Override
          public Dimension getPreferredSize() {
              return dims;
          }
      }