2011-11-20 21 views
12

Estoy dibujando una representación gráfica de la información que genera mi simulación. Tengo el gráfico que muestra, pero el problema que me encuentro es poder guardarlo como .png. Cuando guarda el png, el archivo es completamente negro, por lo que no guarda mi gráfico, sino que crea un archivo png en blanco. El problema es que estoy teniendo dificultades para descifrar cómo convertir en una Imagen Buffered o en una Imagen Rendered todos mis intentos de cometer eclipse y cuando lo compilo funciona como lo describí anteriormente. ¿Alguna idea o sugerencia? Estuve atascado en esto por un par de semanas y o bien es una solución obvia o no puedo guardarlo como png. Pero a partir de la investigación que he realizado, es posible guardar una imágen 2d de Java como un archivo png, ¿no sé lo que me falta? ¡Un par de ojos frescos serían inmensamente apreciados! Gracias de antemano, agradezco todos y cada uno de los consejos o comentarios con respecto a esto.Guardar una imagen gráfica Java 2d como archivo .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); 
    } 

Respuesta

5

Ver este ejemplo: 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 creará una imagen tamponada del panel y escribir la imagen en un archivo.

+0

Gracias por los enlaces, pude utilizar ambos para que funcione pero al final usé la Imagen de pantalla debido a la estética de la imagen. ¡Muchas gracias muchachos, problema resuelto! – theoreticalyield

0

Parece que en realidad nunca pinta la imagen almacenada en su rutina saveGraph (...).

Después de crear su Imagen Buffered y recuperar el objeto Graphics para esa imagen, llame al método paintComponent de su clase principal pasando ese contexto de gráficos. También creas dos objetos GraphDisplay pero nunca usas ninguno.

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

En este punto su BufferedImage ahora debería tener el mismo dibujo que tenía su panel y usted debería ser capaz de guardar los contenidos.

+0

Implementé lo que sugirió, pero aún así aparece un archivo .png negro, ¿alguna sugerencia? ¡Gracias! – theoreticalyield

+0

Este es el enfoque que inicialmente estaba tratando de implementar, sin embargo, cuando uso TYPE_INT_RGB obtengo un .png completamente negro y cuando uso TYPE_INT_ARGB obtengo un archivo png gris sin nada representado. Debe ser algo que me falta ... ¡Gracias de nuevo! – 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(); 
    } 
} 
Cuestiones relacionadas