使用缓冲图像

时间:2016-11-05 14:50:34

标签: java swing jframe bufferedimage 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);
 }
}

1 个答案:

答案 0 :(得分:4)

您正在创建两个 BufferedImage对象 - 一个是从中获取Graphics上下文并在其上绘制文本的对象,另一个是通过ImageIO获取的图片,您 don' t 在上面绘制文字。你返回后者,所以有意义的是图片没有新文本。

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

解决方案:不要这样做,只创建一个 BufferedImage,比如说通过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,而不是绘制,事实上你的问题提到了paintComponent,所以我不确定你为什么要这样做。
  • 你正在重写一个绘画方法,但没有调用超级方法,打破了绘画链。
  • 您在绘图方法中不必要地重复执行文件I / O,这种方法对GUI的感知响应性影响最大,因此您不想这样做。读取一次中的图像将其存储到变量中,使用paintComponent中的变量,永远不要在绘制方法中执行文件I / O.
  • 您需要学习并使用Java naming conventions。变量名都应以较低的字母开头,而类名以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他代码。