2013-05-15 2 views
2

Я пытаюсь создать простую программу с кистью, подобной инструменту, при открытии она создала JFrame, и в ней я помещаю холст, на который пользователь может рисовать. Теперь я пытаюсь сохранить чертеж, используя метод saveCanvas, который вызывается при выходе, но что бы я ни делал, я получаю черное изображение. Вот мой код:Java BufferedImage возвращает черное изображение из Canvas

public class Test{ 

    JFrame f; 
    Canvas c; 
    int x=-1, y=-1; 

    public Test() { 
     f = new JFrame(); 
     f.setSize(1200, 800); 
     c = new Canvas(){ 
      @Override 
      public void paint(Graphics g){ 
       super.paint(g); 
      } 
     }; 
     f.add(c); 
     c.addMouseMotionListener(new MouseMotionListener(){  
      @Override 
      public void mouseMoved(MouseEvent e) { 
       // empty 
      } 
      @Override 
      public void mouseDragged(MouseEvent e){ 
       if(x==-1){ 
        x = e.getX(); 
        y = e.getY(); 
       } 
       c.getGraphics().fillOval(x, y, 5, 5); 
       x = e.getX(); 
       y = e.getY(); 
      } 
     }); 
     f.addWindowListener(new WindowAdapter(){ 
      @Override 
      public void windowClosing(WindowEvent evt) { 
       onExit(); 
      } 
      public void onExit() 
      { 
       saveCanvas(c); 
       System.exit(0); 
      } 
     }); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 

     Test paintBrush = new Test(); 
    } 
    public static void saveCanvas(Canvas canvas){ 

     BufferedImage image=new BufferedImage(canvas.getWidth(), canvas.getHeight(),BufferedImage.TYPE_INT_ARGB); 
     Graphics2D g2=(Graphics2D)image.getGraphics(); 
       boolean x = false; 
       while(!x){ 
        x = g2.drawImage(image, 0, 0, null); 
       } 
     try 
       { 
        ImageIO.write(image, "png", new File("C:\\test\\canvas.png")); 
     } 
       catch (Exception e) { 

     } 
    } 
} 

Любые мысли о том, что может быть причиной этого?

+0

для начала, попробуйте обработать ваше исключение – user902383

+0

Я не получаю никаких исключений, файл сохранен, это всего лишь черный –

+0

Хм, я получил цвет фона с холста в методе savecanvas, его rgb - 238, что означает черный правый? – anshulkatta

ответ

5

Вот что случилось:

  Graphics2D g2=(Graphics2D)image.getGraphics(); 
      boolean x = false; 
      while(!x){ 
       x = g2.drawImage(image, 0, 0, null); 
      } 

Берет Graphics из image и рисования image на эту Graphics. Итак, в основном вы рисуете image на себе.

, что вы хотите, вероятно, больше, как это:

  Graphics2D g2=(Graphics2D)image.getGraphics(); 
      canvas.print(g2); 
      ... 

Теперь рассмотрим следующие замечания, а также:

  • Не используйте Canvas (AWT), но вместо того, чтобы использовать JPanel (и переопределение paintComponent) или JLabel с BufferedImage (нарисовать на GraphicsBufferedImage и позвонить по телефону repaint() на JLabel) (Качели)
  • Не используйте getGraphics на любом компоненте, используйте Graphics при условии, в методе paintComponent

Маленький демонстрационный пример того, что я говорю:

import java.awt.Desktop; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 

public class Test { 

    JFrame f; 
    JLabel c; 
    BufferedImage image; 
    int x = -1, y = -1; 

    public Test() { 
     f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     image = new BufferedImage(1200, 800, BufferedImage.TYPE_INT_ARGB); 
     c = new JLabel(new ImageIcon(image)); 

     f.add(c); 
     c.addMouseMotionListener(new MouseMotionListener() { 
      @Override 
      public void mouseMoved(MouseEvent e) { 
       // empty 
      } 

      @Override 
      public void mouseDragged(MouseEvent e) { 
       if (x == -1) { 
        x = e.getX(); 
        y = e.getY(); 
       } 
       image.getGraphics().fillOval(x, y, 5, 5); 
       c.repaint(); 
       x = e.getX(); 
       y = e.getY(); 
      } 
     }); 
     f.addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent evt) { 
       onExit(); 
      } 

      public void onExit() { 
       try { 
        File output = new File("C:\\test\\canvas.png"); 
        if (!output.getParentFile().exists()) { 
         output.getParentFile().mkdirs(); 
        } 
        ImageIO.write(image, "png", output); 
        Desktop.getDesktop().open(output); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       Test paintBrush = new Test(); 
      } 
     }); 
    } 

} 
+0

ok Я также выяснял, как получить холст, чтобы нарисовать изображение, но не смог сохранить холст в png-файле. – anshulkatta

1
// Create a buffered image: 
    BufferedImage image=new BufferedImage(canvas.getWidth(), 
     canvas.getHeight(),BufferedImage.TYPE_INT_ARGB); 

    // Get the g2 to draw with on the image: 
    Graphics2D g2= (Graphics2D)image.getGraphics(); 

    // Let the canvas component do a paintComponent on the image: 
    SwingUtilities.paintComponent(g2, canvas, frame, 0, 0, 
     canvas.getWidth(), canvas.getHeight()); 

    ImageIO.write(image, "png", new File("C:\\test\\canvas.png")); 

Вместо холста (по общему признанию вводящее в заблуждение имя, особенно сейчас с HTML 5) используют JPanel.

В paintComponent все рисунки, подобные fillOval, должны быть выполнены. Добавить Shape-s или - проще? - добавьте данные, описывающие, что нужно сделать.

В программе Paint есть несколько учебников по рисованию.

+0

Хорошо, я заменил холст на JPANEL, и я попытался сделать то, что предложил @Joop Eggen, теперь я получаю изображение с фоном JPanel (любопытное серое), но без моих рисунков .... –

Смежные вопросы