在缓冲图像上绘图

Drawing on a buffered image

我正在尝试在缓冲图像上绘图。我能够在相框上获得图片,但它似乎无法在图像上绘制。如果我使用

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);
 }
}

您正在创建 两个 BufferedImage 对象——一个您从中获取图形上下文并在其上绘制文本,另一个保存通过 ImageIO 获得的图片,您不要 在上面绘制文字。你 return 后者,所以图片没有新文本是有道理的。

    // 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

解决方案:不要这样做,只创建 one BufferedImage,比如通过 ImageIO,获取它的 Graphics 上下文,用它绘制,dispose 图形完成后,return 它。

例如,

// 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 的方法,打破了绘画链。
  • 您在绘画方法中不必要地重复执行文件 I/O,这种方法对您的 GUI 的感知响应能力影响最大,因此您不想做的事情。读取 中的图像一次 将其存储到变量中,在 paintComponent 中使用该变量,并且永远不要在绘画方法中执行文件 I/O。
  • 您将想要学习和使用 Java naming conventions。变量名称应全部以小写字母开头,而 class 名称应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。