2011-11-20 145 views
12

我绘制了模拟生成信息的图形表示。我有图形显示,但我遇到的问题是能够将其保存为.png。当它保存PNG时,文件全是黑色的,所以它不会保存我的图形,而是创建一些空白PNG文件。问题是我很难搞清楚如何投射到BufferedImage或RenderedImage所有我在eclipse中的尝试抛出错误,当我得到它编译时,它的工作原理如上所述。任何想法或建议?我已经坚持了几个星期,无论是明显的修复还是我无法将其保存为PNG。但从我进行的研究中,可以将java 2d图形img保存为png文件,我不知道我错过了什么?一双新鲜的眼睛将受到极大的赞赏!在此先感谢您,我感谢您对此提出的任何建议或意见。将Java 2d图形图像保存为.png文件

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); 
    } 

回答

5

看到这个例子: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(); 
    } 

    } 
} 
3

Screen Image将创建面板的缓冲的图像和该图像写入到文件中。

+0

感谢您的链接,我能够使用它们都得到它的工作,但最终使用屏幕图像,因为图像美学。非常感谢你们,问题解决了! – theoreticalyield

0

看来,你实际上从来没有在saveGraph(..)例程中绘制到BufferedImage。

创建BufferedImage并检索该图像的Graphics对象后,请调用传递该图形上下文的主类的paintComponent方法。您还创建两个GraphDisplay对象,但从不使用任何一个。

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); 

此时,您的BufferedImage应该具有与您的面板相同的图形,并且您应该可以保存内容。

+0

我实现了你的建议,但它仍然呈现一个黑色的.png文件,有什么建议吗?谢谢! – theoreticalyield

+0

这是我最初试图实现的方法,但是,当我使用TYPE_INT_RGB时,我得到一个全黑.png,并且当我使用TYPE_INT_ARGB时,我得到一个灰色的png文件,没有任何呈现给它。必须是我想念的东西...再次感谢! – theoreticalyield

19
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(); 
    } 
}