在缓冲图像上绘图

baw*_*awa 1 java swing bufferedimage jframe paintcomponent

我正在尝试绘制缓冲图像。我能够在框架上获取图片,但它似乎没有在图像上绘制。如果我使用

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);
 }
}
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 8

您正在创建两个BufferedImage 对象——一个从中获取 Graphics 上下文并在其上绘制文本,另一个保存通过 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
Run Code Online (Sandbox Code Playgroud)

解决方案:不要这样做,只创建一个BufferedImage,比如通过 ImageIO,获取它的 Graphics 上下文,用它绘制,完成后处理Graphics,然后返回它。

例如,

// 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;
}
Run Code Online (Sandbox Code Playgroud)

您的代码的其他问题在这里:

public void paint(Graphics g) {
   Image img = createImageWithText();
   g.drawImage(img, 20,20,this);
}
Run Code Online (Sandbox Code Playgroud)

问题包括:

  • 你覆盖了错误的绘画方法。您应该覆盖paintComponent,而不是paint,实际上您的问题提到了paintComponent,所以我不确定您为什么要这样做。
  • 您正在覆盖绘画方法但没有调用超级方法,从而破坏了绘画链。
  • 您在绘制方法中不必要地重复执行文件 I/O,该方法对 GUI 的感知响应性影响最大,因此是您不想做的事情。一次读取图像将其存储到变量中,在paintComponent 中使用该变量,并且永远不要在绘制方法中进行文件I/O。
  • 您将需要学习和使用Java 命名约定。变量名应全部以小写字母开头,而类名应以大写字母开头。学习这一点并遵循这一点将使我们能够更好地理解您的代码,并使您更好地理解其他人的代码。