绘画不保存到缓冲图像
paint not saving to bufferedimage
当我在 paintComponent()
中包含所有绘图代码时,下面的代码正确地将图表绘制到 JPanel
。但是我想将结果保存到硬盘上的图像文件中以供其他地方使用。因此,我将绘图代码移动到 updatePaint()
方法中,并采取了下面显示的其他步骤首先绘制到 bufferedimage
,然后让 bufferedimage
可用于打印到 JPanel
和到保存的文件。问题是下面的代码只打印了一个黑色 JPanel
而不是我重新排列代码之前正在绘制的图表。
如何更改下面的代码,以便缓冲图像显示预期的图表,并正确绘制到 JPanel,而不影响其保存到文件的能力?
package somepackage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ChartPanel extends JPanel {
private BufferedImage paintImage = new BufferedImage(500, 400, BufferedImage.TYPE_3BYTE_BGR);
private double[] values;
private String[] names;
private String title;
private double fac_result;
public ChartPanel(double[] v, String[] n, String t, double fac_res) {
names = n;
values = v;
title = t;
fac_result = fac_res;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(paintImage, 0, 0, null);
}
// draw painting
public void updatePaint(){
Graphics g = paintImage.createGraphics();
// draw on paintImage using Graphics
if (values == null || values.length == 0)
return;
double minValue = 0;
double maxValue = 0;
for (int i = 0; i < values.length; i++) {
if (minValue > values[i])
minValue = values[i];
if (maxValue < values[i])
maxValue = values[i];
}
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int barWidth = clientWidth / values.length;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
double scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
System.out.println("fac_result in paintComponent() is: "+fac_result);
for (int i = 0; i < values.length; i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = (int) (values[i] * scale);
if (values[i] >= 0)
valueY += (int) ((maxValue - values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
System.out.println("names["+i+"] is: "+names[i]);
if((Double.parseDouble(names[i])<=(fac_result+0.5))&&(Double.parseDouble(names[i])>=(fac_result-0.5))){
g.setColor(Color.cyan);
g.fillRect(valueX, valueY, barWidth - 2, height);
System.out.println("condition met.");
}
else{
g.setColor(Color.red);
g.fillRect(valueX, valueY, barWidth - 2, height);
}
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 2, height);
if(i%5==0){
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(names[i], x, y);
}
}
///////////
g.dispose();
// repaint panel with new modified paint
repaint();
}
public void save() throws IOException{
ImageIO.write(paintImage, "PNG", new File("C:\Temp\filename.png"));
}
public void load() throws IOException {
paintImage = ImageIO.read(new File("C:\Temp\filename.png"));
// update panel with new paint image
repaint();
}
}
注意:以上代码是从另一个 class 使用以下行调用的:
new ChartPanel(values, names, label, fac_result));
- 要更新
BufferedImage
的状态,您可以检查 paintImage
是否为 null
并在调用 paintComponent
时创建和呈现它。
- 就像任何绘画一样,您必须在绘画之前清除
Graphics
上下文。凭记忆,将颜色设置为透明色,并在绘制之前使用clearRect
将内容清除回透明状态。
当我在 paintComponent()
中包含所有绘图代码时,下面的代码正确地将图表绘制到 JPanel
。但是我想将结果保存到硬盘上的图像文件中以供其他地方使用。因此,我将绘图代码移动到 updatePaint()
方法中,并采取了下面显示的其他步骤首先绘制到 bufferedimage
,然后让 bufferedimage
可用于打印到 JPanel
和到保存的文件。问题是下面的代码只打印了一个黑色 JPanel
而不是我重新排列代码之前正在绘制的图表。
如何更改下面的代码,以便缓冲图像显示预期的图表,并正确绘制到 JPanel,而不影响其保存到文件的能力?
package somepackage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ChartPanel extends JPanel {
private BufferedImage paintImage = new BufferedImage(500, 400, BufferedImage.TYPE_3BYTE_BGR);
private double[] values;
private String[] names;
private String title;
private double fac_result;
public ChartPanel(double[] v, String[] n, String t, double fac_res) {
names = n;
values = v;
title = t;
fac_result = fac_res;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(paintImage, 0, 0, null);
}
// draw painting
public void updatePaint(){
Graphics g = paintImage.createGraphics();
// draw on paintImage using Graphics
if (values == null || values.length == 0)
return;
double minValue = 0;
double maxValue = 0;
for (int i = 0; i < values.length; i++) {
if (minValue > values[i])
minValue = values[i];
if (maxValue < values[i])
maxValue = values[i];
}
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int barWidth = clientWidth / values.length;
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int titleWidth = titleFontMetrics.stringWidth(title);
int y = titleFontMetrics.getAscent();
int x = (clientWidth - titleWidth) / 2;
g.setFont(titleFont);
g.drawString(title, x, y);
int top = titleFontMetrics.getHeight();
int bottom = labelFontMetrics.getHeight();
if (maxValue == minValue)
return;
double scale = (clientHeight - top - bottom) / (maxValue - minValue);
y = clientHeight - labelFontMetrics.getDescent();
g.setFont(labelFont);
System.out.println("fac_result in paintComponent() is: "+fac_result);
for (int i = 0; i < values.length; i++) {
int valueX = i * barWidth + 1;
int valueY = top;
int height = (int) (values[i] * scale);
if (values[i] >= 0)
valueY += (int) ((maxValue - values[i]) * scale);
else {
valueY += (int) (maxValue * scale);
height = -height;
}
System.out.println("names["+i+"] is: "+names[i]);
if((Double.parseDouble(names[i])<=(fac_result+0.5))&&(Double.parseDouble(names[i])>=(fac_result-0.5))){
g.setColor(Color.cyan);
g.fillRect(valueX, valueY, barWidth - 2, height);
System.out.println("condition met.");
}
else{
g.setColor(Color.red);
g.fillRect(valueX, valueY, barWidth - 2, height);
}
g.setColor(Color.black);
g.drawRect(valueX, valueY, barWidth - 2, height);
if(i%5==0){
int labelWidth = labelFontMetrics.stringWidth(names[i]);
x = i * barWidth + (barWidth - labelWidth) / 2;
g.drawString(names[i], x, y);
}
}
///////////
g.dispose();
// repaint panel with new modified paint
repaint();
}
public void save() throws IOException{
ImageIO.write(paintImage, "PNG", new File("C:\Temp\filename.png"));
}
public void load() throws IOException {
paintImage = ImageIO.read(new File("C:\Temp\filename.png"));
// update panel with new paint image
repaint();
}
}
注意:以上代码是从另一个 class 使用以下行调用的:
new ChartPanel(values, names, label, fac_result));
- 要更新
BufferedImage
的状态,您可以检查paintImage
是否为null
并在调用paintComponent
时创建和呈现它。 - 就像任何绘画一样,您必须在绘画之前清除
Graphics
上下文。凭记忆,将颜色设置为透明色,并在绘制之前使用clearRect
将内容清除回透明状态。