Drawing on a buffered image(在缓冲图像上绘图)
问题描述
我正在尝试在缓冲图像上绘图.我能够在框架上获得图片,但它似乎没有在图像上绘制.如果我使用
I am trying to draw on a buffered image. I am able to get the picture on the frame but it doesnt seem to draw on the image. If I use
BufferedImage bufferedImage = new BufferedImage(1280, 800,BufferedImage.TYPE_INT_RGB);
然后它似乎在绘制字符串,但我想理想地在图像上绘制,因为我需要在图像上为项目绘制一些坐标.任何指导将不胜感激.请原谅不好的缩进
then it seems to draw the string but I would like to ideally draw on the image as I need to plot some coordinates on the image for a project. Any guidance would be highly appreciated. Excuse the bad indentation
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 对象 - 一个从中获取 Graphics 上下文并在其上绘制文本,另一个用于保存通过 ImageIO 获得的图片,您不要在其上绘制文本.您返回后者,因此图片不包含新文本是有道理的.
You're creating two BufferedImage objects -- one that you get the Graphics context from and draw text on, and the other that holds the picture obtained via ImageIO, that you don't draw text on. You return the latter, so it makes sense that the picture holds no new text.
// 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,然后退货.
Solution: don't do this, create one BufferedImage only, say via ImageIO, get its Graphics context, draw with it, dispose the Graphics when done, and return it.
例如,
// 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;
}
您的代码存在其他问题:
Other problems with your code is here:
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 命名约定.变量名应全部以小写字母开头,而类名应以大写字母开头.学习并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解他人的代码.
- You're overriding the wrong painting method. You should override paintComponent, not paint, and in fact your question mentions paintComponent, so I'm not sure why you're doing this.
- You're overriding a painting method but not calling the super's method, breaking the painting chain.
- You're doing file I/O unnecessarily repeatedly within a painting method, a method that has the greatest effect on the perceived responsiveness of your GUI, and so something you don't want to do. Read the image in once store it to a variable, use the variable within paintComponent, and never do file I/O within a painting method.
- You will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
这篇关于在缓冲图像上绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在缓冲图像上绘图
基础教程推荐
- 在螺旋中写一个字符串 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01