将 Jpanel 写入缓冲图像堆栈溢出
Writing Jpanel to Buffered Image stack overflow
我正在尝试将 JPanel 图片写入 BufferedImage(稍后转换为渲染图像)。由于某种原因,我在 AWT-EventQueue-0 线程中收到堆栈溢出错误,我不确定是否有我忽略的原因。
有问题的代码:
public BufferedImage createImage() {
int w = getWidth();
int h = getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
cp.paint(bi.getGraphics());
//debug script
File outputfile = new File("image"+index+".jpg");
try {
ImageIO.write(bi, "jpg", outputfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
index++;
return bi;
}
JPanel paintComponent
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
r = new Random(System.nanoTime());
int maxSize = 100;
int randX = r.nextInt(getWidth());
int randY = r.nextInt(getHeight());
int randWidth = r.nextInt(maxSize);
int randHeight = r.nextInt(maxSize);
Color color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
Graphics2D g2d = (Graphics2D) g;
ovals.add(new MyCircles(randX, randY, randWidth, randHeight, color));
for (MyCircles c : ovals) {
c.paint(g2d);
}
g2d.setColor(getForeground());
repaint();
double current = ImageComparator.calcDistance((RenderedImage)createImage());
//debugging script
System.out.println("Current: " + current);
System.out.println("Previous" + previous);
if(current > previous) {
ovals.remove(ovals.size()-1);
}
else {
previous = current;
}
}
任何有关如何修改此问题的见解都将不胜感激!
删除 paintComponent
中对 repaint
的调用,这会导致该方法被无限调用
与你的问题没有直接关系,但是,你不应该在绘画方法中使用随机class。每次调用该方法时,绘画都会发生变化,因此您创建和保存的图像将与面板上的图像不同。
此外,出于与上述相同的原因,您不应在绘画方法中添加椭圆。
您需要创建一个 addOval(...)
方法来设置椭圆的随机颜色并将椭圆添加到列表中。绘画代码只会遍历列表并绘制椭圆。
您也不应该在绘画代码中删除椭圆。绘画代码仅用于绘画,不对绘制的对象进行操作。
您也可以尝试 Screen Image class,它基本上是图像创建代码的更灵活的版本。
当然你有无限循环:
这里是你如何调用你的方法:
createImage()
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
TOY STORY 1 (Buzz) : to the infinite and beyond it :)
你永远不会停止这个循环。
我建议您需要获取图像,然后将它们与您的油漆进行比较。让 paint 只绘制图像并在图像外部进行比较。
我正在尝试将 JPanel 图片写入 BufferedImage(稍后转换为渲染图像)。由于某种原因,我在 AWT-EventQueue-0 线程中收到堆栈溢出错误,我不确定是否有我忽略的原因。
有问题的代码:
public BufferedImage createImage() {
int w = getWidth();
int h = getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
cp.paint(bi.getGraphics());
//debug script
File outputfile = new File("image"+index+".jpg");
try {
ImageIO.write(bi, "jpg", outputfile);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
index++;
return bi;
}
JPanel paintComponent
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
r = new Random(System.nanoTime());
int maxSize = 100;
int randX = r.nextInt(getWidth());
int randY = r.nextInt(getHeight());
int randWidth = r.nextInt(maxSize);
int randHeight = r.nextInt(maxSize);
Color color = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256));
Graphics2D g2d = (Graphics2D) g;
ovals.add(new MyCircles(randX, randY, randWidth, randHeight, color));
for (MyCircles c : ovals) {
c.paint(g2d);
}
g2d.setColor(getForeground());
repaint();
double current = ImageComparator.calcDistance((RenderedImage)createImage());
//debugging script
System.out.println("Current: " + current);
System.out.println("Previous" + previous);
if(current > previous) {
ovals.remove(ovals.size()-1);
}
else {
previous = current;
}
}
任何有关如何修改此问题的见解都将不胜感激!
删除 paintComponent
中对 repaint
的调用,这会导致该方法被无限调用
与你的问题没有直接关系,但是,你不应该在绘画方法中使用随机class。每次调用该方法时,绘画都会发生变化,因此您创建和保存的图像将与面板上的图像不同。
此外,出于与上述相同的原因,您不应在绘画方法中添加椭圆。
您需要创建一个 addOval(...)
方法来设置椭圆的随机颜色并将椭圆添加到列表中。绘画代码只会遍历列表并绘制椭圆。
您也不应该在绘画代码中删除椭圆。绘画代码仅用于绘画,不对绘制的对象进行操作。
您也可以尝试 Screen Image class,它基本上是图像创建代码的更灵活的版本。
当然你有无限循环:
这里是你如何调用你的方法:
createImage()
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
|__createImage() // again in ImageComparator.calcDistance line
|__paint()
TOY STORY 1 (Buzz) : to the infinite and beyond it :)
你永远不会停止这个循环。
我建议您需要获取图像,然后将它们与您的油漆进行比较。让 paint 只绘制图像并在图像外部进行比较。