Saving a Java 2d graphics image as .png file

2019-01-07 17:12发布

I am drawing a graphical representation of information my simulation is generating. I have the graph displaying but the problem i am running into is to be able to save it as a .png. When it saves the png, the file is all black, so it's not saving my graph but creating some blank png file. The problem is I am having difficulty figuring out how to cast to a BufferedImage or a RenderedImage all of my attempts in eclipse throw errors and when I get it to compile, it works as how I described above. Any thoughts or suggestions? I have been stuck on this for a couple of weeks and either it is an obvious fix or I am not able to save it as png. But from the research i have conducted, it is possible to save a java 2d graphics img as a png file, I don't know what I am missing? A fresh pair of eyes would be greatly and immensely appreciated! Thank you in advance, I appreciate any and all advice or comments regarding this.

public class GraphDisplay extends JPanel implements RenderedImage  {


    final int PAD = 20; 
    Primate p;


    public GraphDisplay(){


    }
    public GraphDisplay(Primate p){
        this.p = p;

    }

    protected void paintComponent(Graphics g) {


        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // now we can get x1,y1,x2,y2
        double tlx= p.getMap().getX1();
        double tly= p.getMap().getY1();
        double brx= p.getMap().getX2();
        double bry= p.getMap().getY2();


        int w = getWidth();
        int h= getHeight();

        ArrayList <Tree> t=  p.getMap().getTrees();

        ArrayList<Double> xHist = p.getXHist();
        ArrayList<Double> yHist = p.getYHist();


        ArrayList<Double> testxHist = new ArrayList();
        ArrayList<Double> testyHist = new ArrayList();
        for(double i=34;i<1000;i+=5)
        {
            testxHist.add(i);
        }
        for(double i=34;i<1000;i+=5)
        {
            testyHist.add(i);
        }


        // Draw lines.

        double scale=.45;
        g2.setBackground(Color.WHITE);
        g2.setPaint(Color.green.darker());
        for(int i = 0; i < xHist.size()-1; i++) {
            double x1 = PAD + (xHist.get(i)-tlx)*scale;
            double y1 = (tly-yHist.get(i))*scale-PAD;
            double x2 = PAD + (xHist.get(i+1)-tlx)*scale;
            double y2 = (tly-yHist.get(i+1))*scale-PAD;
            g2.draw(new Line2D.Double(x1, y1, x2, y2));
        }
        // Mark path points


        if(p.getRoute()!=null)
        {
            ArrayList<Double> routeX= p.getRoute().getX();
            ArrayList<Double> routeY= p.getRoute().getY();


            g2.setPaint(Color.pink);
            for(int i = 0; i < routeX.size()-1; i++) {
                double x1 = PAD + (routeX.get(i)-tlx)*scale;
                double y1 = (tly-routeY.get(i))*scale-PAD;
                double x2 = PAD + (routeX.get(i+1)-tlx)*scale;
                double y2 = (tly-routeY.get(i+1))*scale-PAD;
                g2.draw(new Line2D.Double(x1, y1, x2, y2));
            }



    }
        g2.setPaint(Color.red);
        for(int i = 0; i < xHist.size(); i++) {

            double x = PAD + (xHist.get(i)-tlx)*scale;
            double y = (tly-yHist.get(i))*scale-PAD;

            g2.fill(new Ellipse2D.Double(x-.75, y-.75, 1.5, 1.5));
        }
        //testing purposes
        g2.setPaint(Color.BLACK);
        for(int i=0;i<t.size();i++)
        {
            double x= PAD+(t.get(i).getX()-tlx)*scale;
            double y= (tly-t.get(i).getY())*scale-PAD;
            g2.fill(new Ellipse2D.Double(x-1,y-1,2,2));
        }

    }


    public class GraphListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            saveGraph(p);
        }
    }



    public void saveGraph(Primate p)
    {   
        ImageIcon saveIcon = new ImageIcon("save.png");
        GraphDisplay graphImg = new GraphDisplay(p);

        Object graph = new GraphDisplay(p);
        BufferedImage buffGraph = new BufferedImage(500,500, BufferedImage.TYPE_INT_RGB);
        graph = buffGraph.createGraphics();
        RenderedImage rendGraph = (RenderedImage) graphImg;

        String graphFileName = JOptionPane.showInputDialog("Please enter a name for the S1Mian graphical output file: ");

        File f;
        f = new File(graphFileName + ".png");

        //every run is unique so do not allow the user to overwrite previously saved files...
        if(!f.exists())
        {
            try{

                ImageIO.write(buffGraph, "png", f);
                JOptionPane.showMessageDialog(null, graphFileName + ".png has been created and saved to your directory...", "File Saved", JOptionPane.INFORMATION_MESSAGE, saveIcon);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }


        }
        else{

            JOptionPane.showMessageDialog(null, graphFileName +".png already exists please use a different file name...", "File Exists", JOptionPane.INFORMATION_MESSAGE, saveIcon);

        }

    }



    public void createGraph(Primate p)
    {

        JFrame frame = new JFrame("S1Mian Graphical Output");
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //disabled now that graphical output is integrated into GUI as when clicked shut down entire program...
        JPanel savePanel = new JPanel();
        ImageIcon saveIcon = new ImageIcon("saveIcon.png");

        JButton save = new JButton("Save");
        save.setToolTipText("Saves the S1Mian graphical output to a .png file");
        save.setIcon(saveIcon);
        GraphListener gl = new GraphListener();
        save.addActionListener(gl);


        GraphDisplay graph = new GraphDisplay(p);
        graph.setPreferredSize(new Dimension(950, 900));

        JScrollPane graphScrollPane = new JScrollPane();
        graphScrollPane.setViewportView(graph);
        graphScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        frame.getContentPane().add(graphScrollPane, BorderLayout.CENTER);

        savePanel.add(save);
        frame.getContentPane().add(savePanel, BorderLayout.NORTH);

        frame.setSize(900,850);
        frame.setLocation(200,200);
        frame.setVisible(true);
    }

4条回答
一纸荒年 Trace。
2楼-- · 2019-01-07 17:43

It appears that you never actually paint to the BufferedImage in your saveGraph(..) routine.

After you create your BufferedImage and retrieve the Graphics object for that image, call the paintComponent method of your main class passing that graphics context. You also are create two GraphDisplay objects but never use either one.

    GraphDisplay graphImg = new GraphDisplay(p);

   //You don't need this one, you created one above named graphImg
   // Object graph = new GraphDisplay(p);
    BufferedImage buffGraph = new BufferedImage(500,500, BufferedImage.TYPE_INT_RGB);

    //get the graphics context for the BufferedImage
    Graphics2D graph = buffGraph.createGraphics();

    //now tell your main class to draw the image onto the BufferedImage
    graphImg.paintComponent(graph);

At this point your BufferedImage should now have the same drawing that your panel had and you should be able to save the contents.

查看更多
三岁会撩人
3楼-- · 2019-01-07 17:47
JPanel dPanel;
...     
public void save()
{
    BufferedImage bImg = new BufferedImage(dPanel.getWidth(), dPanel.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D cg = bImg.createGraphics();
    dPanel.paintAll(cg);
    try {
            if (ImageIO.write(bImg, "png", new File("./output_image.png")))
            {
                System.out.println("-- saved");
            }
    } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
    }
}
查看更多
萌系小妹纸
4楼-- · 2019-01-07 17:48

Screen Image will create a buffered image of the panel and write the image to a file.

查看更多
一夜七次
5楼-- · 2019-01-07 17:57

See this example: Draw an Image and save to png.


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class WriteImageType {
  static public void main(String args[]) throws Exception {
    try {
      int width = 200, height = 200;

      // TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed
      // into integer pixels
      BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

      Graphics2D ig2 = bi.createGraphics();


      Font font = new Font("TimesRoman", Font.BOLD, 20);
      ig2.setFont(font);
      String message = "www.java2s.com!";
      FontMetrics fontMetrics = ig2.getFontMetrics();
      int stringWidth = fontMetrics.stringWidth(message);
      int stringHeight = fontMetrics.getAscent();
      ig2.setPaint(Color.black);
      ig2.drawString(message, (width - stringWidth) / 2, height / 2 + stringHeight / 4);

      ImageIO.write(bi, "PNG", new File("c:\\yourImageName.PNG"));
      ImageIO.write(bi, "JPEG", new File("c:\\yourImageName.JPG"));
      ImageIO.write(bi, "gif", new File("c:\\yourImageName.GIF"));
      ImageIO.write(bi, "BMP", new File("c:\\yourImageName.BMP"));

    } catch (IOException ie) {
      ie.printStackTrace();
    }

  }
}
查看更多
登录 后发表回答