所以,我正在尝试绘制一个绘图程序,我添加了一些功能,但现在我希望能够保存图片。我打开程序,画一幅画,保存它,一切正常!除了图像现在是完全黑色的事实。提前谢谢!
(请告诉我,因为我还是一名学习Java程序员的人,所以我的代码有不好的地方,将来会对我有很大帮助)
课程:
主要课程:
import javax.swing.JFrame;
public class Test{
public static void main(String args[]){
Ploofer ploof = new Ploofer();
ploof.setSize(1000, 950);
PumpkinPie f = new PumpkinPie(ploof);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000,1000);
f.setResizable(false);
f.setVisible(true);
f.setLayout(null);
f.add(ploof);
}
}
" Ploofer"类:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import javax.swing.JPanel;
public class Ploofer extends JPanel{
private static boolean calledOnce = false;
private BufferedImage img = new BufferedImage(1000, 950, BufferedImage.TYPE_INT_RGB);
static private Color backgroundColor = null;
private PumpkinPie pObj;
@Override
public void paintComponent(Graphics g){
if(calledOnce == false){
pObj = new PumpkinPie(this);
calledOnce = true;
}
super.paintComponent(g);
private Graphics2D g2d = img.createGraphics();
if(pObj.colour != null){
g2d.setColor(pObj.colour);
}
else{
g2d.setColor(Color.BLACK);
}
if(pObj.setToBackgroundColor == true){
pObj.colour = backgroundColor;
pObj.setToBackgroundColor = false;
}
if(pObj.changeBackgroundColor == true){
backgroundColor = pObj.colour;
this.setBackground(backgroundColor);
g2d.setBackground(backgroundColor);
pObj.changeBackgroundColor = false;
update(g2d);
update(g);
}
if(pObj.wipe == true){
g2d.clearRect(0, 0, img.getWidth(), img.getHeight());
g.dispose();
g2d.setBackground(Color.WHITE);
g.drawImage(img, 0, 0, null);
pObj.wipe = false;
repaint();
}
if(pObj.draw == true){
g2d.fillRect(pObj.x, pObj.y, 8, 8);
pObj.draw = false;
}
if(img != null){
g.drawImage(img, 0, 0, null);
}
}
public BufferedImage getImage(){
return img;
}
}
"南瓜派"类:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
public class PumpkinPie extends JFrame{
public int x;
public int y;
static public boolean draw = false;
static public boolean changeBackgroundColor = false;
static public boolean setToBackgroundColor = false;
static public boolean wipe = false;
static public Color colour = Color.WHITE;
Box box;
private JMenuBar menuBar;
private JMenu file, edit;
private JMenuItem save, saveas, exit, open, clear, changeBackground;
private JPanel colourButton;
private JButton saveButton;
private Icon eraser;
private JLabel eraserLabel;
private JFileChooser fc;
Ploofer ploof = new Ploofer();
public PumpkinPie(JPanel panel){
super("SPLAT! SPLAT!");
file = new JMenu("File");
edit = new JMenu("Edit");
box = Box.createHorizontalBox();
menuBar = new JMenuBar();
open = new JMenuItem("Open file");
save = new JMenuItem("Save");
saveas = new JMenuItem("Save as...");
exit = new JMenuItem("Exit");
clear = new JMenuItem("Clear");
changeBackground = new JMenuItem("Change background color");
colourButton = new JPanel();
eraserLabel = new JLabel();
eraser = new ImageIcon(getClass().getResource("/Resources/Eraser.png"));
fc = new JFileChooser();
fc.setCurrentDirectory(new File("C:\\Users\\" + System.getProperty("user.name") + "\\Pictures"));
fc.setDialogTitle("Choose a location...");
saveButton = new JButton("Save");
panel.setSize(1000, 950);
panel.setLocation(0, 50);
colourButton.setSize(50, 50);
colourButton.setBorder(BorderFactory.createLineBorder(Color.BLACK));
eraserLabel.setIcon(eraser);
eraserLabel.setSize(50, 50);
eraserLabel.setLocation(50, 0);
this.setJMenuBar(menuBar);
setLayout(new BorderLayout());
menuBar.add(file);
menuBar.add(edit);
file.add(open);
file.add(save);
file.add(saveas);
file.add(exit);
edit.add(clear);
edit.add(changeBackground);
setLayout(null);
add(colourButton);
add(eraserLabel);
MouseMoveHandlerer mouseMoveHandler = new MouseMoveHandlerer();
MouseHandlerer mouseHandler = new MouseHandlerer();
ButtonHandlerer buttonHandler = new ButtonHandlerer();
panel.addMouseMotionListener(mouseMoveHandler);
eraserLabel.addMouseListener(mouseHandler);
clear.addActionListener(buttonHandler);
colourButton.addMouseListener(mouseHandler);
changeBackground.addActionListener(buttonHandler);
save.addActionListener(buttonHandler);
saveas.addActionListener(buttonHandler);
}
private class MouseMoveHandlerer extends MouseMotionAdapter{
public void mouseDragged(MouseEvent event){
x = event.getX();
y = event.getY();
draw = true;
repaint();
}
}
private class MouseHandlerer extends MouseAdapter{
public void mouseClicked(MouseEvent event){
if(event.getSource() == colourButton){
colour = JColorChooser.showDialog(null, "Choose a colour", colour);
colourButton.setBackground(colour);
}
else if(event.getSource() == eraserLabel){
setToBackgroundColor = true;
repaint();
colourButton.setBackground(colour);
}
}
}
private class ButtonHandlerer implements ActionListener{
@Override
public void actionPerformed(ActionEvent event) {
if(event.getSource() == save){
}
else if(event.getSource() == saveas){
if(fc.showSaveDialog(saveButton) == JFileChooser.APPROVE_OPTION){
try{
ImageIO.write(ploof.getImage(), "PNG", new File(fc.getSelectedFile().getPath() + ".png"));
}catch(Exception e){
e.printStackTrace();
}
}
}
else if (event.getSource() == clear){
wipe = true;
repaint();
}
else{
changeBackgroundColor = true;
repaint();
}
}
}
}
答案 0 :(得分:2)
无法真正遵循您的绘画逻辑,但有一些评论:
不要直接调用update(...)。 Swing将在适当的时候调用该方法。绘画方法只应关注绘画逻辑。
不要使用paintComponent()方法来创建BufferedImage。使用BufferedImage的目的是将图像一次绘制到BufferedImage上,然后在paintComponent()方法中绘制BufferedImage。
如果您每次都要重新创建BufferedImage,那么您也可以直接绘制到面板的Graphics。既然你似乎有一堆可以改变的变量,我猜你应该直接把它画到面板上,不要担心BufferedImage。
除了图像现在是完全黑色的事实
您可以根据需要创建BufferedImage,而不是尝试在paintCompnent()方法中创建图像。查看ScreenImage课程。它允许您创建任何Swing组件的图像。
使用此类创建/保存图像的代码类似于
BufferedImage bi = ScreenImage.createImage(yourPanel);
ScreenImage.writeImage(bi, "panel-image.png");
您可能还想查看Custom Painting Approaches以了解在BufferedImage上绘画和在paintComponent()方法中绘画之间的区别。
答案 1 :(得分:0)
所以,我解决了!如果有人需要同样的帮助,我会在这里发布解决方案!这有点像作弊,但它有效!
基本上我创建了一个名为" ScreenCapture"
的新课程 private class ScreenCapture{
Dimension d = new Dimension(980, 896);
public void takePicture(Point i, File file){
BufferedImage image;
try {
image = new Robot().createScreenCapture(new Rectangle(i, d));
ImageIO.write(image, "PNG", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
无论什么时候我想打电话,我都会这样做:
try{
ScreenCapture screenCap = new ScreenCapture();
screenCap.takePicture(getScreenPlace(), new File(fc.getSelectedFile().getPath() + ".png"));
}catch(Exception e){
e.printStackTrace();
}
getScreenPlace()函数仅获取并更改JFrame的屏幕位置
private Point getScreenPlace(){
this.setLocation(0, 0);
Point location = getLocation();
location.setLocation(location.getX()+3, location.getY()+100);
return location;
}
我需要移动框架,因为如果有任何其他方式它将在图片上。感谢@camickr帮助我
(另外,为什么我不测量屏幕尺寸的原因仅仅是因为我设置屏幕尺寸的方式无法改变)