在缓冲图像上绘图
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 名称应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。
我正在尝试在缓冲图像上绘图。我能够在相框上获得图片,但它似乎无法在图像上绘制。如果我使用
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 名称应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。