user3150201
user3150201

Reputation: 1947

Trying to draw BufferedImage to file, doesn't work

I'm trying to convert a JPanel to a BufferedImage, and then save that image to a file.

DrawingPanel is a class that extends JPanel.

public class J extends JFrame {

    public J(){

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(500,500);

        DrawingPanel panel = new DrawingPanel();
        add(panel);

        BufferedImage bi = (BufferedImage) panel.createImage(500,500);
        File file = new File("file.png");

        setVisible(true);

        try {
            ImageIO.write(bi, "PNG", file);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

I get an error: IllegalArgumentException: image == null! This error happens in this line:

ImageIO.write(bi, "PNG", file);

What is the problem? Thanks

EDIT: The DrawingPanel class:

public class DrawingPanel extends JPanel {

    public void paintComponent(Graphics g){

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        setBackground(Color.BLACK);

    }

}

Upvotes: 1

Views: 456

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285450

It's hard to guess your problem since your DrawingPanel is not available to us, but it could be due to your trying to get your image before the GUI has rendered it, and in fact before it has rendered anything at all, which occurs only after calling setVisible(true) on your JFrame.

e.g.,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageFoo extends JFrame {

   public ImageFoo() {

      setDefaultCloseOperation(EXIT_ON_CLOSE);
      // setSize(500, 500);
      DrawingPanel panel = new DrawingPanel();
      add(panel);

      // BufferedImage bi = (BufferedImage) panel.createImage(500, 500);
      // File file = new File("file.png");

      pack();
      setLocationRelativeTo(null);
      setVisible(true);

      BufferedImage bi = (BufferedImage) panel.createImage(500, 500);
      File file = new File("file.png");
      try {
         ImageIO.write(bi, "PNG", file);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   private static void createAndShowGui() {
      JFrame frame = new ImageFoo();
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

}

class DrawingPanel extends JPanel {

   private static final int PREF_W = 500;
   private static final int PREF_H = PREF_W;

   public DrawingPanel() {
      setBackground(Color.black);
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      Paint paint = new GradientPaint(0, 0, Color.red, 20, 20, Color.blue, true);
      g2.setPaint(paint);
      g2.fillOval(0, 0, PREF_W, PREF_H);
      // setBackground(Color.BLACK); // never do in paintComponent
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

}

Edit: I like this attempt better

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageFoo extends JFrame {

   public ImageFoo() {

      setDefaultCloseOperation(EXIT_ON_CLOSE);
      // setSize(500, 500);
      final DrawingPanel panel = new DrawingPanel();
      add(panel);

      // BufferedImage bi = (BufferedImage) panel.createImage(500, 500);
      // File file = new File("file.png");

      pack();
      setLocationRelativeTo(null);
      setVisible(true);

      new Thread(new Runnable() {
         public void run() {
            // try {
            //    Thread.sleep(300);
            // } catch (InterruptedException e1) {
            // }
            // BufferedImage bi = (BufferedImage) panel.createImage(500, 500);

            BufferedImage bi = new BufferedImage(DrawingPanel.PREF_W,
                  DrawingPanel.PREF_H, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = bi.createGraphics();
            panel.paintAll(g2);
            g2.dispose();
            File file = new File("file.png");
            try {
               ImageIO.write(bi, "PNG", file);
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }).start();
   }

   private static void createAndShowGui() {
      JFrame frame = new ImageFoo();
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }

}

class DrawingPanel extends JPanel {

   public static final int PREF_W = 500;
   public static final int PREF_H = PREF_W;

   public DrawingPanel() {
      setBackground(Color.black);
   }

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      Paint paint = new GradientPaint(0, 0, Color.red, 20, 20, Color.blue, true);
      g2.setPaint(paint);
      g2.fillOval(0, 0, PREF_W, PREF_H);
      // setBackground(Color.BLACK); // never do in paintComponent
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

}

Upvotes: 6

Related Questions