2011-11-20 2 views
12

Sto disegnando una rappresentazione grafica delle informazioni che la mia simulazione sta generando. Ho il display grafico ma il problema che sto incontrando è quello di essere in grado di salvarlo come un file .png. Quando salva il png, il file è tutto nero, quindi non sta salvando il mio grafico ma creando un file png vuoto. Il problema è che ho difficoltà a capire come lanciare su BufferedImage o RenderedImage tutti i miei tentativi di eclissi generano errori e quando riesco a compilare, funziona come descritto sopra. Qualche idea o suggerimento? Sono stato bloccato su questo per un paio di settimane e o è una soluzione ovvia o non sono in grado di salvarlo come PNG. Ma dalla ricerca che ho condotto, è possibile salvare un img di grafica java 2d come un file png, non so cosa mi manca? Un nuovo paio di occhi sarebbe grandemente e immensamente apprezzato! Grazie in anticipo, apprezzo qualsiasi consiglio o commento in merito.Salvataggio di un'immagine grafica Java 2d come file .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); 
    } 

risposta

5

Vedere questo esempio: 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 creerà un'immagine tamponata del pannello e scrivere l'immagine in un file.

+0

Grazie per i collegamenti, sono stato in grado di utilizzare entrambi per farlo funzionare ma alla fine ho utilizzato l'immagine dello schermo a causa dell'estetica dell'immagine. Grazie mille ragazzi, problema risolto! – theoreticalyield

0

Sembra che non si dipingi mai effettivamente in BufferedImage nella routine saveGraph (..).

Dopo aver creato BufferedImage e recuperato l'oggetto Graphics per quell'immagine, chiamare il metodo paintComponent della classe principale che passa il contesto grafico. Inoltre, crei due oggetti GraphDisplay ma non ne usi mai uno.

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

A questo punto il vostro BufferedImage ora dovrebbe avere lo stesso disegno che il vostro pannello aveva e si dovrebbe essere in grado di salvare i contenuti.

+0

Ho implementato ciò che mi hai suggerito, ma rende comunque un file .png nero, qualche suggerimento? Grazie! – theoreticalyield

+0

Questo è l'approccio che inizialmente stavo cercando di implementare, tuttavia, quando uso TYPE_INT_RGB ottengo un file .png tutto nero e quando uso TYPE_INT_ARGB ottengo un file png grigio con niente di rendering. Deve essere qualcosa che mi manca ... Grazie ancora! – 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(); 
    } 
}