【问题标题】:Drawing on a buffered image在缓冲图像上绘图
【发布时间】:2016-11-05 23:07:31
【问题描述】:

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

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

【问题讨论】:

    标签: java swing jframe bufferedimage paintcomponent


    【解决方案1】:

    您正在创建 两个 BufferedImage 对象 - 一个用于获取 Graphics 上下文并在其上绘制文本,另一个用于保存通过 ImageIO 获得的图片,您不要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,获取其 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;
    }
    

    您的代码存在其他问题:

    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。变量名应全部以小写字母开头,而类名应以大写字母开头。学习这一点并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。

    【讨论】:

    • 是的,我知道它是一个糟糕的代码 atm。这只是一个测试文件。我之前没有使用过缓冲图像,所以试图绕过它。不过谢谢你,仍然有帮助。如果还可以指导我如何在不像素化的情况下调整图像大小,那就太好了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2018-02-12
    • 2021-06-05
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多