代码之家  ›  专栏  ›  技术社区  ›  devpa

如何使用java awt绘制图像?[副本]

  •  0
  • devpa  · 技术社区  · 7 年前

    我正在尝试绘制缓冲图像。我能在相框上看到照片,但它似乎无法在图像上画出来。如果我使用

    BufferedImage bufferedImage = new BufferedImage(1280, 800,BufferedImage.TYPE_INT_RGB);

    然后,它似乎绘制字符串,但我希望理想地在图像上绘制,因为我需要在图像上为项目绘制一些坐标。如有任何指导,我们将不胜感激。请原谅错误的缩进

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class drawTest extends JPanel {
    
    public void paint(Graphics g) {
       Image img = createImageWithText();
       g.drawImage(img, 20,20,this);
    }
    
    private Image createImageWithText(){
       BufferedImage bufferedImage = new BufferedImage(1280, 800,BufferedImage.TYPE_INT_RGB);
     //   BufferedImage bufferedImage = new BufferedImage()
      Graphics g = bufferedImage.getGraphics();
    
      try {
        bufferedImage = ImageIO.read(getClass().getResource("Unknown.jpg"));
    
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      g.drawString("Point is here", 20,20);
    
    
      return bufferedImage;
    }
    
      public static void main(String[] args) {
        JFrame frame = new JFrame();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        double width = screenSize.getWidth();
        double height = screenSize.getHeight();
        frame.getContentPane().add(new drawTest());
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     // frame.setSize(200, 200);
    
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        System.out.println(height + " " + width); 
        frame.setVisible(true);
     }
    }
    
    0 回复  |  直到 9 年前
        1
  •  9
  •   Hovercraft Full Of Eels    9 年前

    您正在创建 BuffereImage对象——一个用于获取图形上下文并在其上绘制文本,另一个用于保存通过ImageIO获得的图片 不要 在上绘制文本。返回后者,因此图片中没有新文本是有意义的。

        // BufferedImage Object ONE
        BufferedImage bufferedImage = new BufferedImage(1280, 800, BufferedImage.TYPE_INT_RGB); 
        Graphics g = bufferedImage.getGraphics();  // Graphics for the first object only
    
        try {
            // BufferedImage object TWO
            bufferedImage = ImageIO.read(getClass().getResource("Unknown.jpg"));
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        // draw with the graphics context for the first object
        g.drawString("Point is here", 20, 20);
    
        return bufferedImage; // but return the second
    

    解决方案:不要这样做,创建 仅BuffereImage,例如通过ImageIO,获取其图形上下文,使用它绘制, 处置 完成后返回图形。

    例如。,

    // have method accept the image path and 
    // have it throw an exception if the path is bad
    private Image createImageWithText2(String resourcePath) throws IOException {
    
        // create one and only one BufferedImage object. 
        // If this fails, the exception will bubble up the call chain
        BufferedImage bufferedImage = ImageIO.read(getClass().getResource(resourcePath));
    
        // get the Graphics context for this single BufferedImage object 
        Graphics g = bufferedImage.getGraphics();  
    
        g.drawString("Point is here", 20, 20);
    
        g.dispose();  // get rid of the Graphics context to save resources
    
        return bufferedImage;
    }
    

    代码的其他问题如下:

    public void paint(Graphics g) {
       Image img = createImageWithText();
       g.drawImage(img, 20,20,this);
    }
    

    问题包括:

    • 您覆盖了错误的绘制方法。你应该重写paintComponent,而不是paint,事实上你的问题提到了paintComponent,所以我不知道你为什么要这么做。
    • 您正在重写绘制方法,但没有调用super的方法,从而破坏了绘制链。
    • 您在绘制方法中重复进行不必要的文件输入/输出,这种方法对GUI的感知响应性影响最大,因此您不想这样做。在中读取图像 一旦 将其存储到变量中,在paintComponent中使用该变量,不要在绘制方法中进行文件I/O。
    • 您将想要学习和使用 Java naming conventions . 变量名都应该以小写字母开头,而类名应该以大写字母开头。学习并遵循这一点可以让我们更好地理解您的代码,也可以让您更好地理解其他人的代码。